Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Tkinter GUI Application Development Cookbook

You're reading from   Tkinter GUI Application Development Cookbook A practical solution to your GUI development problems with Python and Tkinter

Arrow left icon
Product type Paperback
Published in Mar 2018
Publisher Packt
ISBN-13 9781788622301
Length 242 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Alejandro Rodas de Paz Alejandro Rodas de Paz
Author Profile Icon Alejandro Rodas de Paz
Alejandro Rodas de Paz
Arrow right icon
View More author details
Toc

Table of Contents (10) Chapters Close

Preface 1. Getting Started with Tkinter FREE CHAPTER 2. Window Layout 3. Customizing Widgets 4. Dialogs and Menus 5. Object-Oriented Programming and MVC 6. Asynchronous Programming 7. Canvas and Graphics 8. Themed Widgets 9. Other Books You May Enjoy

Handling mouse and keyboard events

Being able to react to events is one of the most basic but important topics in GUI application development since it determines how users can interact with the program.

Pressing keys of the keyboard and clicking on items with the mouse are some common types of events, which are automatically handled in some Tkinter classes. For instance, this behavior is already implemented on the command option of the Button widget class, which invokes the specified callback function.

Some events can get triggered without user interaction, such as changing the input focus programmatically from one widget to another.

How to do it...

You can attach an event binding 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("<Button-1>", self.print_event) 
        frame.bind("<Double-Button-1>", self.print_event) 
        frame.bind("<ButtonRelease-1>", self.print_event) 
        frame.bind("<B1-Motion>", self.print_event) 
        frame.bind("<Enter>", self.print_event) 
        frame.bind("<Leave>", 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() method of our class, which prints the type of event and the position of the mouse in the console. You can try it out by clicking on the green frame with the mouse, and moving it around while it starts printing the event messages.

The following example contains an Entry widget with a couple of bindings; one for the event that gets triggered when the entry gets the focus, and another for all the key press events:

import tkinter as tk 
 
class App(tk.Tk): 
    def __init__(self): 
        super().__init__() 
        entry = tk.Entry(self) 
        entry.bind("<FocusIn>", self.print_type)  
        entry.bind("<Key>", 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("Symbol: {}, Code: {}, Char: {}".format(*args)) 
 
if __name__ == "__main__": 
    app = App() 
    app.mainloop() 

The first message this program will output is the FocusIn event when you set the focus on the Entry widget. If you try it out, you will see that it will also show the events of keys that do not correspond to non-printable characters, such as arrow keys or the return key.

How it works...

The bind method is defined in the widget class and takes three arguments, an event sequence, a callback function, and an optional add string:

widget.bind(sequence, callback, add='') 

The sequence string uses the <modifier-type-detail> syntax.

In first place, modifiers are optional and allow you to specify additional combinations to the general type of the event:

  • Shift: When the user presses the Shift key
  • Alt: When the user presses the Alt key
  • Control: When the user presses the Ctrl key
  • Lock: When the user presses the Shift lock
  • Double: When the event happens twice in quick succession
  • Triple: When the event happens thrice in quick succession

Event types determine the general type of event:

  • ButtonPress or Button: Event generated when a mouse button is pressed
  • ButtonRelease: Event generated when a mouse button is released
  • Enter: Event generated when you move the mouse over a widget
  • Leave: Event generated when the mouse pointer leaves a widget
  • FocusIn: Event generated when the widget gets the input focus
  • FocusOut: Event generated when the widget loses the input focus
  • KeyPress or Key: Event generated when a key is pressed
  • KeyRelease: Event generated when a key is released
  • Motion: Event generated when the mouse is moved

The detail is also optional and serves to indicate the mouse button or key:

  • For mouse events, 1 is the left button, 2 is the middle button, and 3 is the right button.
  • For keyboard events, it is the key character. Special keys use the key symbol; some common examples are return, Tab, Esc, up, down, right, left, Backspace, and function keys (from F1 to F12).

The callback function takes an event parameter. For mouse events, it has the following attributes:

  • x and y: Current mouse position in pixels
  • x_root and y_root: Same as x and y, but relative to the left-upper corner of the screen
  • num: Mouse button number

For keyboard events, it contains these attributes:

  • char: Pressed character code as a string
  • keysym: Pressed key symbol
  • keycode: Pressed key code

In both cases, the event has the widget attribute, referencing the instance that generated the event, and type, which specifies the event type.

We strongly recommend that you define methods for the callback functions since you will also have the reference to the class instance, and therefore you can easily access each of the widget attributes.

Finally, the add parameter can be '', to replace the callback function if there was a previous binding, or '+' to add the callback and preserve the old ones.

There's more...

Apart from the event types described here, there are also other types that may be useful in some scenarios, such as the <Destroy> event that is generated when a widget is destroyed or the <Configure> event that is sent when the size or position of the widget changes.

You can check out the Tcl/Tk documentation for a complete list of event types at https://www.tcl.tk/man/tcl/TkCmd/bind.htm#M7.

See also

  • The Structuring a Tkinter application recipe
You have been reading a chapter from
Tkinter GUI Application Development Cookbook
Published in: Mar 2018
Publisher: Packt
ISBN-13: 9781788622301
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image