From Jared.Cohen at noaa.gov Thu Aug 19 17:32:56 2004 From: Jared.Cohen at noaa.gov (Jared Cohen) Date: Thu Aug 19 17:33:15 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird Message-ID: <4124C828.5080106@noaa.gov> Hi all. I'm currently using a Tkinter Scale widget which uses a DoubleVar as its control variable. I then use the "trace_variable('w', callback)" method to invoke a callback whenever the DoubleVar changes. The problem is this: the callback is triggered when the slider moves (as it should), but it's also triggered when I just HOVER the mouse over the slider without clicking! Somehow or other, it must think that the control variable is being changed, even though it isn't. I *think* that this problem is related to the loss of precision that DoubleVars can have, but I'm not really sure. Has anyone else experienced this problem? How can I fix this? As an aid, here's a quick stub program that illustrates the problem. Try (for example) moving the slider to 0.3, release the mouse button, then move the mouse pointer back and forth over the slider WITHOUT clicking. Each time the pointer passes over the slider, it will print the value. import sys, Tkinter, types root = Tkinter.Tk() var = Tkinter.DoubleVar() def callback(*args): print var.get() var.trace_variable("w", callback) slider = Tkinter.Scale(root, from_ = 0.0, to = 1.0, resolution = 0.1, variable = var, orient = 'horizontal') slider.grid(sticky='ew') root.mainloop() -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/tkinter-discuss/attachments/20040819/51d0f1e8/attachment.html From klappnase at freenet.de Thu Aug 19 22:41:35 2004 From: klappnase at freenet.de (Michael Lange) Date: Thu Aug 19 22:45:03 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird In-Reply-To: <4124C828.5080106@noaa.gov> References: <4124C828.5080106@noaa.gov> Message-ID: <20040819224135.10a6aae3.klappnase@freenet.de> On Thu, 19 Aug 2004 11:32:56 -0400 "Jared Cohen" wrote: > Hi all. I'm currently using a Tkinter Scale widget which uses a > DoubleVar as its control variable. I then use the "trace_variable('w', > callback)" method to invoke a callback whenever the DoubleVar changes. > > The problem is this: the callback is triggered when the slider moves (as > it should), but it's also triggered when I just HOVER the mouse over the > slider without clicking! Somehow or other, it must think that the > control variable is being changed, even though it isn't. I *think* that > this problem is related to the loss of precision that DoubleVars can > have, but I'm not really sure. Has anyone else experienced this problem? > How can I fix this? > > As an aid, here's a quick stub program that illustrates the problem. Try > (for example) moving the slider to 0.3, release the mouse button, then > move the mouse pointer back and forth over the slider WITHOUT clicking. > Each time the pointer passes over the slider, it will print the value. > > > import sys, Tkinter, types > > root = Tkinter.Tk() > var = Tkinter.DoubleVar() > > def callback(*args): > print var.get() > > var.trace_variable("w", callback) > > slider = Tkinter.Scale(root, > from_ = 0.0, > to = 1.0, > resolution = 0.1, > variable = var, > orient = 'horizontal') > slider.grid(sticky='ew') > > root.mainloop() > Hi Jared, that's interesting, I never noticed this behavior, probably because I used callbacks where excess calls didn't matter. To avoid excess calls to your callback() you might consider to store the value of var in a second variable like this: var = Tkinter.DoubleVar() oldvalue = var.get() def callback(*args): global oldvalue if var.get() != oldvalue: oldvalue = var.get() print var.get() I hope this helped Michael From jepler at unpythonic.net Fri Aug 20 14:07:12 2004 From: jepler at unpythonic.net (Jeff Epler) Date: Fri Aug 20 14:07:37 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird In-Reply-To: <4124C828.5080106@noaa.gov> References: <4124C828.5080106@noaa.gov> Message-ID: <20040820120712.GB24118@unpythonic.net> I do *not* see this behavior on fedora-release-2-4 (Fedora Core 2 Linux) python-2.3.3-6 tcl-8.4.5-7 tk-8.4.5-6 However, while dragging I can see a set to the same value multiple times. I suppose this happens when the mouse movement is too small to move one "resolution" unit. You could use a class which acts as a function wrapper to eliminate the redundant calls to "callback": class RedundancyEliminator: def __init__(self, var, callback): self.var = var self.callback = callback self.lastval = var.get() def __call__(self, *args): newval = var.get() if newval != self.lastval: self.lastval = newval return self.callback(*args) return None def callback(*args): print var.get() var.trace_variable("w", RedundancyEliminator(var, callback)) Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://mail.python.org/pipermail/tkinter-discuss/attachments/20040820/859782d5/attachment.pgp From Jared.Cohen at noaa.gov Fri Aug 20 16:04:30 2004 From: Jared.Cohen at noaa.gov (Jared Cohen) Date: Fri Aug 20 16:04:53 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird Message-ID: <412604EE.6070802@noaa.gov> Thanks to both of you for your help. I already do have mechanisms in place that prevent the callback from actually doing anything if the variable has not really been changed. But the problem with that method (and with both of your suggestions) is that even if the callback doesn't do anything, it is still getting invoked when it shouldn't be. I was simply trying to figure out WHY, because I felt that it would be more elegant to completely stop the callback from getting invoked incorrectly, than to allow it to be invoked and then have it return without doing anything. But if that's not feasible, then I'll just have to do it the other way :-) -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/tkinter-discuss/attachments/20040820/2f077a00/attachment.html From klappnase at web.de Sat Aug 21 01:09:16 2004 From: klappnase at web.de (Michael Lange) Date: Sat Aug 21 01:12:54 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird In-Reply-To: <412604EE.6070802@noaa.gov> References: <412604EE.6070802@noaa.gov> Message-ID: <20040821010916.1f200147.klappnase@web.de> On Fri, 20 Aug 2004 10:04:30 -0400 "Jared Cohen" wrote: > Thanks to both of you for your help. I already do have mechanisms in > place that prevent the callback from actually doing anything if the > variable has not really been changed. But the problem with that method > (and with both of your suggestions) is that even if the callback doesn't > do anything, it is still getting invoked when it shouldn't be. I was > simply trying to figure out WHY, because I felt that it would be more > elegant to completely stop the callback from getting invoked > incorrectly, than to allow it to be invoked and then have it return > without doing anything. But if that's not feasible, then I'll just have > to do it the other way :-) > Maybe you could bind your callback to ButtonRelease- and KeyRelease events instead of using var.trace_variable() (or the scale's command option), however it may be a little complicated to get exactly the behavior you want. BTW, I noticed this behavior, too, on both python2.2.2 / tk8.3.3 and python2.3.3 / tk8.4.5; unfortunately I don't have a clue, what's the reason for this either. Michael From clnethery at juno.com Sun Aug 22 08:24:26 2004 From: clnethery at juno.com (Chris Nethery) Date: Sun Aug 22 13:48:24 2004 Subject: [Tkinter-discuss] Hiding and unhiding frames and/or widgets in general Message-ID: <20040821.232502.15747.374661@webmail10.nyc.untd.com> First, I recall now that I neglected to thank everyone for their help, concerning my last question. The last two months have been extraordinarily busy, although that's a poor excuse for bad manners, so thank you all, belatedly, for your assistance. I am back again, with another (possibly silly) question regarding hiding and unhiding windows. I notice that toplevel windows have the ability to be "withdrawn" or "deiconified" in order to be hidden from view. My widgets are not toplevel widgets, so I'm unclear about whether or not I can use these methods or not. Either way, I am trying (unsuccessfully) to accomplish something similar, in that I would like to destroy or withdraw an entryfield widget if a comboBox is displayed, and visa versa. Also, if neither an entryfield or a comboBox is displayed, nothing should be displayed in the same spot. The following code illustrates, to some degree, what I'm trying to accomplish. But you'll note that the code has other problems as well: import Pmw from Tkinter import * root = Tk() Pmw.initialise(root) class Stuff: def __init__(self, root): self.root = root self.mainframe = Frame(self.root) self.mainframe.pack(fill='both', expand=1, padx=5, pady=5) self.choices = [ '', 'Select the entryField...', 'Select the entryField again...', 'Select the entryField yet again...', ] self.choices2 = [ '', 'Select the comboBox...', 'Select the comboBox again...', 'Select the comboBox yet again...', ] self.stuffList = [ '', 'item 1', 'item 2', 'item 3', 'item 4', 'item 5', 'item 6', 'item 7', 'item 8', 'item 9', 'item 10', ] self.cBox = Pmw.ComboBox( self.mainframe, listheight=225, selectioncommand=self.createEntryField, entry_width=28, labelmargin=1, labelpos='w', label_text='Select stuff:', scrolledlist_items=self.choices+self.choices2) self.cBox.pack() self.eFrame = Frame(self.mainframe, borderwidth=0, width=200, height=22, relief=GROOVE) self.eField = Pmw.EntryField( self.eFrame, labelpos=W, label_text='Enter Stuff:', labelmargin=2, entry_width=12, validate = None, ) self.eField.pack() self.cFrame = Frame(self.mainframe, borderwidth=0, width=200, height=22, relief=GROOVE) self.cBox2 = Pmw.ComboBox( self.cFrame, listheight=165, entry_width=12, labelmargin=9, labelpos='w', label_text='Stuff:', scrolledlist_items=self.stuffList ) self.cBox2.pack() def createEntryField(self, hello): for item in self.choices: if self.cBox.component('entryfield').component('entry').get() == item: self.cFrame.lower() self.eFrame.lift() self.eFrame.place(relx=0.7, rely=0.08, anchor=NW) else: self.eFrame.lower() self.cFrame.lift() self.cFrame.place(relx=0.7, rely=0.08, anchor=NW) if __name__=='__main__': stuff = Stuff(root) root.mainloop() Any ideas? Thanking you in advance, Christopher Nethery From jepler at unpythonic.net Sun Aug 22 18:41:19 2004 From: jepler at unpythonic.net (Jeff Epler) Date: Sun Aug 22 18:41:37 2004 Subject: [Tkinter-discuss] Hiding and unhiding frames and/or widgets in general In-Reply-To: <20040821.232502.15747.374661@webmail10.nyc.untd.com> References: <20040821.232502.15747.374661@webmail10.nyc.untd.com> Message-ID: <20040822164119.GD2348@unpythonic.net> If you are using "pack" to manage your widgets, then "pack_forget" will make the widget disappear. Similarly, there are "grid_forget" and "place_forget" methods. When a widget is packed or unpacked, the size of its containing frame may change, and that propogates up in the widget hierarchy to the toplevel. Having the window change size when a field appears or disappears is probably going to be jarring to the eye. You can "fix" this by turning off "geometry propagation" in the frame that contains the changing widget. This is done by the grid_propagate or pack_propagate method of the *container* object. from Tkinter import * def size_for_alternatives(parent, kids): w = max([k.winfo_reqwidth() for k in kids]) h = max([k.winfo_reqheight() for k in kids]) print ([k.winfo_reqwidth() for k in kids]), w print ([k.winfo_reqheight() for k in kids]), h parent.pack_propagate(0) parent.grid_propagate(0) parent.configure(width=w, height=h) def swap(): if v.get(): e.pack_forget() mb.pack(anchor="w", side="left") else: mb.pack_forget() e.pack(anchor="w", side="left") e.focus() t = Tk() v = IntVar(t) c = Checkbutton(t, command=swap, text="Order from menu?", variable=v) c.pack(anchor="w") f1 = Frame(t) l = Label(f1, text="Your order:") l.pack(side="left") f = Frame(f1) f.pack(side="left") e = Entry(f, width=18) mb = Menubutton(f, width=8, text="eggs", indicatoron=1, relief="sunken", anchor="w") m = Menu(mb, tearoff=0); mb.configure(menu=m) for s in "eggs bacon sausage spam".split(): m.add_command(label=s, command=lambda s=s: mb.configure(text=s)) f.after_idle(lambda: size_for_alternatives(f, (e, mb))) f.pack() f1.pack() swap() b = Button(t, text="Place order", command=t.destroy); b.pack(side="top") f.mainloop() -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://mail.python.org/pipermail/tkinter-discuss/attachments/20040822/abc562be/attachment.pgp From fredrik at pythonware.com Mon Aug 23 13:50:34 2004 From: fredrik at pythonware.com (Fredrik Lundh) Date: Mon Aug 23 13:50:38 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird References: <412604EE.6070802@noaa.gov> Message-ID: Jared Cohen wrote: > I was simply trying to figure out WHY, because I felt that it would be more > elegant to completely stop the callback from getting invoked incorrectly, than > to allow it to be invoked and then have it return without doing anything. But > if that's not feasible, then I'll just have to do it the other way :-) Note that I did test my snippet, and it doesn't behave as you describe on any platform I tested it on. So it's either a platform issue, or a pro- blem with the exact version of Tk you're using. If you really want to pursue this, you could report the bug to the Tk folks. From jepler at unpythonic.net Mon Aug 23 16:31:18 2004 From: jepler at unpythonic.net (Jeff Epler) Date: Mon Aug 23 16:31:30 2004 Subject: [Tkinter-discuss] Please help -- Tkinter Scale widget with DoubleVar is acting weird In-Reply-To: <4124C828.5080106@noaa.gov> References: <4124C828.5080106@noaa.gov> Message-ID: <20040823143117.GF7899@unpythonic.net> I looked into this some more, and was able to reproduce the problem using tcl-8.3.5-88 redhat-release-9-3 I was then also able to demonstrate it on tcl/tk 8.5. I used this wish script: scale .s -variable v -resolution 0.1 -from 0 -to 1 trace variable v w changed proc changed {args} { global v; puts "v changed. new value: $v" } pack .s I set the scale value to 0.7. Now, by moving the cursor *between the slider and the trough*, I get the repeated message "v changed. new value: 0.7". (It's the movement between slider and trough, not just hovering, that made the redundant sets happen for me) This behavior doesn't seem to depend on the value of tcl_precision. It *looks* like the problem is in TkRoundToResolution(). It returns a slightly different value than the incoming value, so that the test "scalePtr->value == value" in tkUnixScale:TkpSetScaleValue() fails and it falls through to a Tcl_SetVar call. This is low-level stuff inside of tk. Like Fredrik suggested, your next step is to go to the tcl/tk community with your report, if it's important to you. Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://mail.python.org/pipermail/tkinter-discuss/attachments/20040823/ec8eed35/attachment.pgp