Creating The Python UI With Tkinter
Written by Alex Armstrong   
Wednesday, 14 November 2012
Article Index
Creating The Python UI With Tkinter
Events

Events

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:

 

EventDescription
<Button-1>

Left mouse button down (click)

<B1-Motion> Mouse moved with left button down (drag)
<ButtonRelease-1> Left mouse button released
<Double-Button-1> a double click
<Enter> The mouse pointer entered the widget
<Leave> The mouse pointer left the widget.
<Return> The user pressed the Enter key.
<Key> The user pressed any key. 
<Configure> The widget changed size

 

The Event Object

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:

 

AttributeDescription
widget The widget that the event occured on as a reference not as a name.
x, y The current mouse position, in pixels.
x_root, y_root The current mouse position relative to the upper left corner of the screen, in pixels.
char The character code (keyboard events only), as a string.
keysym The key symbol (keyboard events only).
keycode The key code (keyboard events only)
num The button number (mouse button events only)
width, height The new size of the widget, in pixels (Configure events only).
type The event type.

 

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.

Single Threading

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.

 

Related Articles

Arrays in Python

Advanced Python Arrays - Introducing NumPy

The Python Dictionary

Creating The Python UI With Tkinter

Creating The Python UI With Tkinter - The Canvas Widget 

Getting Started with Python

Head First Python (Book Review)

A Concise Introduction to Programming In Python (Book Review)

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)

 

blog comments powered by Disqus

 

Banner

 

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>



Last Updated ( Monday, 22 April 2013 )
 
 

   
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.