Creating The Python UI With Tkinter
Written by Mike James   
Thursday, 01 August 2019
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>
mouse button down (click)
<B1-Motion>
Mouse moved with button down (drag)
<ButtonRelease-1>
mouse button released
<Double-Button-1>
a double click
<Enter>
The mouse pointer entered the widget
<Leave>
The mouse pointer 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 properties 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.

See: Creating The Python UI With Tkinter - The Canvas Widget 

 

  • Mike James is the author of Programmer's Python: Everything is an Object published by I/O Press as part of the  I Programmer Library. With the subtitle "Something Completely Different" this is for those who want to understand the deeper logic in the approach that Python 3 takes to classes and objects.

 

 

Related Articles

Creating The Python UI With Tkinter - The Canvas Widget 

Arrays in Python

Advanced Python Arrays - Introducing NumPy

The Python Dictionary

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)

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 

Banner


Lightbend Announces Akka 3
15/11/2024

Lightbend, the company that developed Akka, has announced Akka 3, and has changed its name to Akka. The company produces cloud-native microservices frameworks, and Akka is used for building distribute [ ... ]



Rust And C++ Should Be Friends?
20/11/2024

The Rust Foundation has just released a statement on Rust and C++ interoperability and Google is ponying up $1000,000 to see that it gets done.


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info

 

<ASIN:1871962587>

<ASIN:B07S1K8KLW>

 



Last Updated ( Monday, 13 April 2020 )