Building a UI is mostly about getting to know how to use the particular widgets that are available. However before you get deeper in it is very important to understand the structure and problems of an asynchronous program.
You can always attach an event handler to a widget using:
widget.bind('<event>',function>
This binds to a single instance of the widget e.g. a particular button. You can also use a class binding which sets the event handler for all instances of the widget. For example
root.bind_class("Button",function)
binds the function to every Button instance.
Some events and event handlers are so commonly used that you can specify them as part of the widget's options when you are creating it. These are the so called command callbacks. For example:
button1=Button(root,text="Hello",command=function)
binds function to the Button's click event. It is just a an easier way of defining an event handler.
Events are specified as:
<modifier-type-detail>
For example
<Button-1>
is mouse button 1 down and
<Double-Button-1>
is button one double clicked.
There are many shortcuts and different ways of writing events.
The most common events are:
Left mouse button down (click)
All event handlers are passed a single parameter - the event object. This contains lots of information in the form of properties about the event that you can use within the event handler.
The most common properites are:
For example:
def transfertext(e): label1.configure(text=e.x)
which writes the mouse x position on the label
or
def transfertext(e): e.widget.configure(text=e.x)
which writes the mouse x position on the widget on which the click occurred, i.e. the Button.
As explained at the start a Tkinter program is different from other Python programs in that it is asynchronous. Once everything is set up and initialized the program enters the event loop and this calls event handlers as events occur.
What is less obvious is that all of this occurs on the same thread of execution. The Tkinter GUI has to run on the main thread and when an event occurs the main thread is used to call you event handler. What this means is that while your event handler is running the event loop isn't running. As long as your event handler doesn't take much time to run then the user doesn't notice.
However if your event handler takes a lot of time to complete its task the then the user will notice that the event loop isn't running because the UI will be unresponsive. That is if the user clicks a button nothing will happen because the event loop isn't running and the event cannot be dispatched to the event handler concerned. When your event handler stops and returns control to the event loop then the UI starts to work about.
What can you do about this?
The simplest solution is to make sure that your event handlers don't take too long to complete.
The second solution is to use the root window's update method in your event handler. This gives the root window a chance to run the event loop and call any event handlers that are needed. This is simple and it sort of works but it carries with it the danger that the long running event handler might be called a second time. It is generally frowned upon as a solution.
The third solution is to use a separate thread to get the work done within the event handler. That is create a new thread and get it to do the long running task. This is the best solution, but threads are an advanced topic and it is easy to get things wrong.
Look out for another article on how to handle this sort of asynchronous problem.
For the moment it is enough that you are aware that you can block the UI if your event handler takes too long to complete.
More on Tkinter programming coming soon.)
Modern Tkinter for Busy Python Developers (book review)
A Concise Introduction to Programming In Python (book review)
Core Python Applications Programming, 3ed Edn. (book review)
To be informed about new articles on I Programmer, subscribe to the RSS feed, follow us on Google+, Twitter, Linkedin or Facebook or sign up for our weekly newsletter.
<ASIN:0132678209>
<ASIN:1439896941>