[Tkinter-discuss] Getting an Entry field to stretch

Lion Kimbro lionkimbro at gmail.com
Thu Jul 4 01:30:13 CEST 2013


  I, too, am a big fan of The Old Way:


import Tkinter as tk

root = tk.Tk()


root.tk.eval("""
package require Tk

frame .f
canvas .f.c -bg red -borderwidth 0 -highlightthickness 0 -yscrollcommand
{.f.vert set}
scrollbar .f.vert -orient vertical -command {.f.c yview}

pack .f.vert -side right -fill y    -expand 0
pack .f.c    -side left  -fill both -expand 1

frame .f.inner -bg blue
.f.c create window 0 0 -anchor nw -window .f.inner -tags {frame}
bind .f.c <Configure> {
  .f.c itemconfigure "frame" -width [ winfo width .f.c ]
  .f.c config -scrollregion [.f.c bbox all]
}

set bg [.f.inner cget -bg]
grid columnconfigure .f.inner 2 -weight 1

for {set row 1} {$row < 20} {incr row} {
  set w .f.inner.rb$row
  set e1 .f.inner.e1$row
  set e2 .f.inner.e2$row
  set e3 .f.inner.e3$row
  radiobutton $w -text "" -variable active -value $row -bg $bg
  entry $e1 -bg "white"
  entry $e2 -bg "white"
  entry $e3 -bg "white"
  grid $w -row $row -column 0 -pady 2
  grid $e1 -row $row -column 1 -sticky ew -pady 2
  grid $e2 -row $row -column 2 -sticky ew -pady 2
  grid $e3 -row $row -column 3 -sticky ew -pady 2
}

set active 1

pack .f -side top -fill both -expand 1
""")

selection = lambda: int(root.tk.eval("expr {$active}"))

val = lambda r,c: root.tk.eval(".f.inner.e%s%s get" % (r, c))


  ;D




On Wed, Jul 3, 2013 at 8:41 AM, Bob Greschke <bob at passcal.nmt.edu> wrote:

> You're as smart as ever! :)  This is nice.
>
> Yeah, I'm not a very object-oriented kinda guy, which is coming in REAL
> handy trying to learn iOS programming where just about every character you
> type in the source code is an object.  My brain is too used to thinking The
> Old Way.
>
> Thanks!
>
> Bob
>
>
> On 2013-07-02, at 15:41, Bryan Oakley <bryan.oakley at gmail.com> wrote:
>
> > This problem requires that you do two things:
> >
> > a) cause the width of the inner frame to resize when the canvas resizes
> > b) make sure the widgets inside the inner frame resize when the inner
> > frame resizes.
> >
> > For a), you need to do a binding on the <Configure> event of the
> > canvas. In the callback for that binding, use the canvas's
> > 'itemconfigure' method to change the width of the inner frame.
> >
> > For b), the easiest is to use the grid geometry manager and do away
> > with all of the inner frames. Then all you need to do is configure the
> > inner frame such that the appropriate column grows and shrinks. Of
> > course, you can use the inner frames if you really want to. In that
> > case you wouldn't use grid, you could use pack, and as long as the
> > inner frames were all packed identically with one entry being told to
> > expand, it will all work just fine.
> >
> > It's hard to retrofit some of that into the code you posted. I'll post
> > some code to illustrate how I would do it. I switched up the style of
> > the app as a whole to something more object-oriented, and I did away
> > with the global imports. I think these two changes make for a better
> > way to write Tkinter apps.
> >
> > import Tkinter as tk
> >
> > class Example(tk.Frame):
> >    def __init__(self, *args, **kwargs):
> >        tk.Frame.__init__(self, *args, **kwargs)
> >
> >        self.activeVar = tk.StringVar()
> >        self.activeVar.set(1)
> >
> >        self.canvas = tk.Canvas(self,
> >                                background="red",
> >                                borderwidth=0,
> >                                highlightthickness=0)
> >        self.vsb = tk.Scrollbar(self, orient="vertical",
> > command=self.canvas.yview)
> >        self.canvas.config(yscrollcommand=self.vsb.set)
> >        self.vsb.pack(side="right", fill="y", expand=False)
> >        self.canvas.pack(side="left", fill="both", expand=True)
> >
> >        self.inner_frame = tk.Frame(self, background="blue")
> >        self.canvas.create_window(0,0,
> >                                  anchor="nw",
> >                                  window=self.inner_frame,
> >                                  tags=("frame",))
> >        self.canvas.bind("<Configure>", self._on_canvas_resize)
> >        self._add_widgets(20)
> >
> >    def _on_canvas_resize(self, event=None):
> >        width = self.canvas.winfo_width()
> >        self.canvas.itemconfigure("frame", width=width)
> >        self.canvas.config(scrollregion=self.canvas.bbox("all"))
> >
> >    def _add_widgets(self, count):
> >        bg = self.inner_frame.cget('background')
> >        self.inner_frame.grid_columnconfigure(2, weight=1)
> >
> >        for row in xrange(1, count):
> >            lrb = tk.Radiobutton(self.inner_frame, text="",
> >                                 variable = self.activeVar,
> >                                 value=str(row),
> >                                 background=bg)
> >            lent1 = tk.Entry(self.inner_frame,  bg = "white")
> >            lent2 = tk.Entry(self.inner_frame,  bg = "white")
> >            lent3 = tk.Entry(self.inner_frame,  bg = "white")
> >
> >            lrb.grid(row=row, column=0, pady=2)
> >            lent1.grid(row=row, column=1, sticky='ew', pady=2)
> >            lent2.grid(row=row, column=2, sticky='ew', pady=2)
> >            lent3.grid(row=row, column=3, sticky='ew', pady=2)
> >
> >
> > if __name__ == "__main__":
> >    root = tk.Tk()
> >    Example(root).pack(side="top", fill="both", expand=True)
> >    root.mainloop()
> >
> > On Tue, Jul 2, 2013 at 3:59 PM, Bob Greschke <bob at passcal.nmt.edu>
> wrote:
> >> This is what I want to do...almost:
> >>
> >> -----
> >> #! /usr/bin/env python
> >>
> >> from Tkinter import *
> >>
> >> Root = Tk()
> >>
> >> RowActiveVar = StringVar()
> >>
> >> LastWidth = 0
> >> Count = 0
> >> def iChanged(e = None):
> >>    global LastWidth
> >>    global Count
> >>    Count += 1
> >>    Geom = Root.geometry()
> >>    Width = int(Geom[:Geom.index("x")])
> >>    if Width == LastWidth:
> >>        return
> >> #    Root.geometry("%d%s"%((Width+ScrollWidth+2),
> Geom[Geom.index("x"):]))
> >>    LastWidth = Width+ScrollWidth+2
> >>    return
> >>
> >> RowSub = Frame(Root, bg = "blue")
> >> RowCan = Canvas(RowSub, bg = "red")
> >> RowCan.pack(side = LEFT, expand = YES, fill = BOTH)
> >> Scroll = Scrollbar(RowSub, orient = VERTICAL, command = RowCan.yview, \
> >>        width = 15)
> >> Scroll.pack(side = RIGHT, fill = Y)
> >> ScrollWidth = int(Scroll.cget("width"))+int(Scroll.cget("bd"))*2+ \
> >>        int(Scroll.cget("highlightthickness"))*2
> >> RowCan.configure(yscrollcommand = Scroll.set)
> >> RowSub.pack(side = TOP, expand = YES, fill = BOTH)
> >>
> >> Y = 0
> >> for I in xrange(1, 20):
> >>    SSub = Frame()
> >>    LRb = Radiobutton(SSub, text = "", variable = RowActiveVar, \
> >>            value = str(I), bg = Frame().cget("bg"))
> >>    LRb.pack(side = LEFT)
> >>    LEnt = Entry(SSub, width = 15, bg = "white")
> >>    LEnt.pack(side = LEFT)
> >> # This one...
> >>    LEnt = Entry(SSub, width = 40, bg = "white")
> >>    LEnt.pack(side = LEFT, expand = YES, fill = X)
> >>    LEnt = Entry(SSub, width = 10, bg = "white")
> >>    LEnt.pack(side = LEFT)
> >>    SSub.pack(expand = YES, fill = X)
> >>    RowCan.create_window(0, Y, anchor = "nw", window = SSub)
> >>    RowCan.update()
> >>    L,T,R,B = RowCan.bbox(ALL)
> >>    Y = B
> >> RowCan.configure(scrollregion = (0, 0, R, B))
> >> Geom = Root.geometry()
> >> LastWidth = R+ScrollWidth+2
> >> Root.geometry("%d%s"%(LastWidth, Geom[Geom.index("x"):]))
> >> Root.bind("<Configure>", iChanged)
> >>
> >> Root.mainloop()
> >> -----
> >>
> >> I'd like the center column of Entry fields to get longer as the window
> width is changed.  I have a static non-scrollbar version of this that works
> fine (Entry fields in a Frame that is packed TOP into another Frame --
> everyone set to expand and fill as needed), but throwing the Canvas and the
> scrolling in there seems to be a problem.  I have another version that uses
> a Text() to hold all of the rows, but I can't get that to work either.  The
> iChanged() stuff really doesn't do anything at this point.  I was thinking
> that might be where a solution goes.  Can it be done?
> >>
> >> Thanks!
> >>
> >> Bob
> >>
> >> _______________________________________________
> >> Tkinter-discuss mailing list
> >> Tkinter-discuss at python.org
> >> http://mail.python.org/mailman/listinfo/tkinter-discuss
> >
>
> _______________________________________________
> Tkinter-discuss mailing list
> Tkinter-discuss at python.org
> http://mail.python.org/mailman/listinfo/tkinter-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20130703/84471ad9/attachment-0001.html>


More information about the Tkinter-discuss mailing list