Download lesson code from GitLab: https://gitlab.com/PythonRu/tkinter-uroki
Table of Contents
Mouse and keyboard events handling
The ability to respond to events is one of the basic but important topics in GUI applications. It’s what determines how users will be able to interact with the program. Pressing keys on the keyboard and clicking on items with the mouse are basic examples of events, all of which are automatically handled in some Tkinter classes. For example, this behavior is already implemented in the command
parameter of the Button
widget class, which calls a certain function. Some events can also be triggered without user input. For example, the input focus can be shifted from one widget to another. You can bind an event to a widget using the bind
method. The following example binds some mouse events to a Frame
instance:
import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__() frame = tk.Frame(self, bg="green", height=100, width=100) frame.bind("", self.print_event) frame.bind("", self.print_event) frame.bind("", self.print_event) frame.bind("", self.print_event) frame.bind("", self.print_event) frame.bind("", self.print_event) frame.pack(padx=50, pady=50) def print_event(self, event): position = "(x={}, y={})".format(event.x, event.y) print(event.type, "event", position) if __name__ == "__main__": app = App() app.mainloop()
All events are handled by the print_event()
class method, which outputs the event type and mouse position in the console. You can experiment by clicking on the green frame with your mouse and moving it while it outputs event messages. The following example contains an input box widget and several bindings. One of them is triggered when the focus is on the widget, and the other is triggered when the button is clicked:
import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__() entry = tk.Entry(self) entry.bind("", self.print_type) entry.bind("", self.print_key) entry.pack(padx=20, pady=20) def print_type(self, event): print(event.type) def print_key(self, event): args = event.keysym, event.keycode, event.char print("Sign: {}, Code: {}, Character: {}".format(*args)) if __name__ == "__main__": app = App() app.mainloop()
The first thing the program does is to display a FocusIn
event message. This will happen the moment the focus is in the Entry widget. You can also make sure that events are triggered in the case of non-printable characters, such as arrow keys or Backspace.
How event tracking works
The bind
method is defined in the widget
class and takes three arguments: the event sequence
, the callback
function, and the optional add
string:
widget.bind(sequence, callback, add='')
The sequence
string uses the syntax . Modifiers are optional and allow you to specify additional combinations for a common event type:
- Shift – when the user presses the Shift key.
- Alt – when the user presses the Alt key.
- Control – When the user presses the Control key.
- Lock – when the user presses the Lock key.
- Shift – when the user presses the Shift key.
- Shift – when the user presses the Shift lock key.
- Double – When an event occurs twice in a row.
- Triple – When an event occurs three times in a row.
Event types define a common event type:
- ButtonPress or Button – events that are generated when the user presses the mouse button.
- ButtonRelease – event when the mouse button is released.
- Enter – the event when the mouse is moved to the widget.
- Leave – the event when the mouse leaves the widget area.
- FocusIn – the event when the input focus comes into the widget.
- FocusOut – event when the widget loses focus of input.
- KeyPress or Key – event for the button press.
- KeyRelease – event for the released button.
- Motion – an event when the mouse moves.
detail
is also an optional parameter that is responsible for defining a specific key or button:
- For mouse events 1 is the left button, 2 is the middle button and 3 is the right button
- For keyboard events the keys themselves are used. If they are special keys, the special symbol is used: enter, Tab, Esc, up, down, right, left, Backspace and function keys (from F1 to F12).
The callback
function takes an event parameter. For mouse events, these are the following attributes:
x
andy
– current mouse position in pixelsx_root
andy_root
– the same as x or y, but relative to the screen top left cornernum
– number of mouse button
For keyboard keys, these are the following attributes:
char
– pressed key as a stringkeysym
– symbol of the pressed keykeycode
– code of the pressed key
In both cases, the event has a widget
attribute that refers to the instance that generated the event and a type
that defines the event type. It is recommended to define a method for the callback
function, since there will always be a reference to an instance of the class, and this way you can easily access the widget
attributes. Finally, the add
parameter can be empty (""
) to replace the callback
function if there was a binding before or +
to add the callback function and keep the old ones. In addition to the event types described, there are others that prove useful in certain scenarios: for example, is generated when the widget is destroyed and
is generated when the size or position is changed. A complete list of events is available in the Tcl/Tk documentation.
Configuring the icon, title and size of the main window
The Tk instance differs from regular widgets in the way it is configured. Let’s take a look at the basic methods that allow you to customize the appearance. This piece of code creates a main window with the specified name and icon. Its width is 400 pixels and its height is 200 pixels. Plus, there is a 10px separation on each axis to the upper left corner of the screen.
import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__() self.title("My App") self.iconbitmap("python.ico") self.geometry("400x200+10+10") if __name__ == "__main__": app = App() app.mainloop()
The program assumes there is a valid ICO file python.ico in the same directory as the script itself. Here is the result:
How the window setup works
The names of the title()
and iconbitmap()
methods of the Tk class speak for themselves. The first one sets up the name of the window and the second one takes the icon path for it. The geometry()
method adjusts the size of the window using a string with the following pattern: {width}x{height}+{of set_x}+{of set_y} If the application has additional windows, the same methods are available in the Toplevel
class. To make the application full-screen, replace the geometry()
method call with self.state("zoomed")
.