On 5/10/2018 2:12 PM, charmingold...@gmail.com wrote:
I'm learning to use TkInter in Python and came across this example program from 
'Thinking in TkInter' (http://thinkingtkinter.sourceforge.net) - see below.

Two buttons 'button1' and 'button2' are defined. The bug is that event.widget 
returns '.!frame.!button' from a button1 event.

The internal pathname of a widget is generated by tkinter for interaction with tk. '.' is the name given to the root Tk widget. Before a couple of years ago, children were given random 8(I believe)-digit names. So you might have seen something like .88023535.29038503. Now, the path component for a widget is '!' + widgetName (+ number suffix if needed). A number suffix is only needed to avoid duplication after the first widget of a given class for a particular parent.

 i.e. it somehow drops the '1' from the widget name.

There never was a '1' to be dropped.


 Events on button2 are correctly reported.

Is this a bug or a feature?

<code>
from tkinter import *

class MyApp:
        def __init__(self, parent):
                self.myParent = parent
                self.myContainer1 = Frame(parent)
                self.myContainer1.pack()
                
                button_name = "OK"
                self.button1 = Button(self.myContainer1,
                        command=self.buttonHandler(button_name, 1, "Good 
stuff!"))

This calls self.buttonHandler and binds the return value, None, to command. Functions bound to 'command' must not require arguments. Add 'lambda:' before 'self' and the above will work. Nothing is printed until you click the button and the printing is repeated each time you click.

                        
                # self.button1.bind("<Return>", self.buttonHandler_a(event, button_name, 
1, "Good stuff!"))

Functions bound to events must take one argument, the event. Add 'lambda event:' before 'self' and the above works when the focus is on button1 and you hit return.

Repeat both fixes for button 2.

                self.button1.configure(text=button_name, background="green")
                self.button1.pack(side=LEFT)
                self.button1.focus_force()  # Put keyboard focus on button1
                
                button_name = "Cancel"
                self.button2 = Button(self.myContainer1,
                        command=self.buttonHandler(button_name, 2, "Bad  
stuff!"))
                        
                # self.button2.bind("<Return>", self.buttonHandler_a(event, button_name, 
2, "Bad  stuff!"))
                self.button2.configure(text=button_name, background="red")
                self.button2.pack(side=LEFT)
                                
                
        def buttonHandler(self, arg1, arg2, arg3):
                print("    buttonHandler routine received arguments:", 
arg1.ljust(8), arg2, arg3)
                
        def buttonHandler_a(self, event, arg1, arg2, arg3):
                print("buttonHandler_a received event", event)
                self.buttonHandler(arg1, arg2, arg3)
                
print("\n"*100) # clear the screen
print("Starting program tt077.")
root = Tk()
myapp = MyApp(root)
print("Ready to start executing the event loop.")
root.mainloop()
print("Finished       executing the event loop.")
</code>



--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to