Ahh - thanks for the clear explanations and the workaround! Do you see these behaviors as "unexpected" enough that I should submit them to someone as something to possibly change in the future, or do you feel that they are appropriate - or at least appropriate enough not to make a change that might break old code?
And if they should be submitted, to whom? Thanks again! Dave "Guilherme Polo" <[EMAIL PROTECTED]> wrote on 11/07/2008 10:32:06 AM: > On Fri, Nov 7, 2008 at 12:53 PM, <[EMAIL PROTECTED]> wrote: > > "Guilherme Polo" <[EMAIL PROTECTED]> wrote on 11/07/2008 09:23:48 AM: > >> > >> Comparing this Scale example with a command set and a Button with a > >> command set is unfair. When you change Scale's value, the scale > >> eventually has to be redraw. > >> > >> So, you create a Scale with the "command" option set, then you change > >> its value by calling scale.set, then you run mainloop. When mainloop > >> runs the scheduled events start firing, and there is one around there > >> saying your scale changed its value so the slider has to be redrawn. > >> But you also set a command, so, since the scale changed now it must be > >> invoked, and the callback is called. > >> > >> Can you explain why is it a problem to invoke the callback if the > >> scale has changed ? And why don't you want it to be called the first > >> time. > >> > >> -- > >> -- Guilherme H. Polo Goncalves > > > > Thanks for the quick response and the explanation about there being a > > scheduled events queue that waiting for the mainloop to start, Guilherme. > > That's something I hadn't thought about and it explains why there is a > > delayed command firing. However, it doesn't change my thinking that the > > command shouldn't be firing at all in these two cases. > > > > First off, I have no problem if the callback is invoked when the scale is > > changed, that is why I'm using it. > > > > However, in the first case, I don't think of the scale being 'changed'. > > I'm giving it the initial value via the Tkinter variable scalevar and I'm > > not changing it, so I don't understand why the command gets called. The > > scale doesn't have to be redrawn, only drawn the first time. Maybe my > > original button argument wasn't the best, but I do see this as the same as > > a Checkbutton. I can pass in an initial value to the Checkbutton via a > > Tkinter variable, and the Checkbutton command does not fire when the > > mainloop starts (see the example below, which I've also fixed so it no > > longer imports a custom module of my own - it should run for anyone now). > > > > And in the second case, there is no command callback registered at the > > time that I change the scale value - the callback is added later via a > > configure statement. So again, I don't see why a callback is registered > > for the change. This behavior is again different from a checkbutton - if > > I create a checkbutton with no callback, then change the value, then add a > > callback function, the callback command is not called. I've added both > > the checkbutton examples to the code below for comparison. > > > > As for why I don't want the callback to be called when the widget is first > > created, well I might have something in my callback routine that I only > > want to occur in response to the user changing the initial scale value. > > Regardless, it seems like quite non-standard and unexpected (to me) > > behavior since other widgets don't do this. > > > > Dave > > > > > > import Tkinter as Tk > > > > root = Tk.Tk() > > def printme1(value): > > print 'Scale # 1 just fired with value:', value > > scalevar = Tk.IntVar() > > scalevar.set(7) > > scale1 = Tk.Scale(root, command=printme1, variable=scalevar) > > print 'Scale #1 initialized with value:', scale1.get() > > > > Ok, it is understandable that you want the callback to not be invoked > in this case, but unfortunately that is how scale works for now. It > may not make a difference to the problem, but the behaviour of > ttk.Scale is the one you are expecting. > > > def printme2(value): > > print 'Scale # 2 just fired with value:', value > > scale2 = Tk.Scale(root) > > print 'Scale #2 initialized with value: ', scale2.get() > > scale2.set(4) > > print 'Scale #2 just set to value: ', scale2.get() > > scale2.configure(command=printme2) > > > > Now this is basically the same as the example in the other email. It > is differently internally in tkScale.c, but will result in the same > actions. Calling scale2.configure includes setting the scale value to > itself to ensure that the scale's value is within the new acceptable > range for the scale (note that you didn't change its range, but > unfortunately it does this anyway). When it goes to set the scale's > value, the scale command is already set (you just gave it one), so it > is scheduled for redrawn and the callback will eventually be called. > > To achieve what you want you will have to drop the "command" option > usage and stick to tcl variables. In the first example in this email > you already used an IntVar, now all you have to do is trace that > variable for changes on it, specially when you write to it. This > means: > > scalevar.trace_variable('w', callback) > > callback is a function that takes 3 arguments, the first is the > variable name, the second is just used if you are using an tcl array > (Tkinter.py doesn't wrap it), and the third argument will be the flags > given to trace_variable ('w' here). > To access the variable value in the callback you would do something > like: root.globalgetvar(varname) where root could be Tkinter.Tk() for > example, and varname would be the first parameter in the callback > function. > > > def printme3(): > > print 'Checkbutton # 1 just fired with value:', cbvar.get() > > cbvar = Tk.IntVar() > > cbvar.set(1) > > cb1 = Tk.Checkbutton(root, variable=cbvar, command=printme3) > > print 'Checkbutton #1 initialized with value: ', cbvar.get() > > > > def printme4(): > > print 'Checkbutton # 2 just fired with value:', cbvar2.get() > > cbvar2 = Tk.IntVar() > > cbvar2.set(1) > > cb2 = Tk.Checkbutton(root, variable=cbvar) > > cb2.invoke() > > print 'Just invoked cb2 with no callback' > > cb2.configure(command=printme4) > > > > print 'Now packing scales' > > scale1.pack() > > scale2.pack() > > cb1.pack() > > print 'Done packing scales' > > > > root.mainloop() > > > > > > -- > -- Guilherme H. Polo Goncalves _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss@python.org http://mail.python.org/mailman/listinfo/tkinter-discuss