Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter: invoke event in main loop

How do you invoke a tkinter event from a separate object?

I'm looking for something like wxWidgets wx.CallAfter. For example, If I create an object, and pass to it my Tk root instance, and then try to call a method of that root window from my object, my app locks up.

The best I can come up with is to use the the after method and check the status from my separate object, but that seems wasteful.

like image 970
Mark Avatar asked Nov 06 '08 22:11

Mark


People also ask

How do you create an event loop in Python tkinter?

For example, clicking on a button generates an event, and the main loop must make the button look like it's pressed down and run our callback. Tk and most other GUI toolkits do that by simply checking for any new events over and over again, many times every second. This is called an event loop or main loop.

How does Mainloop work in tkinter?

mainloop() tells Python to run the Tkinter event loop. This method listens for events, such as button clicks or keypresses, and blocks any code that comes after it from running until you close the window where you called the method.

Can you use while loops in tkinter?

You can use while and for loops without blocking the GUI. This is currently for Tkinter and PyQT.

What does TK update do?

Python Tkinter Mainloop Update Update() method in mainloop in Python Tkinter is used to show the updated screen. It reflects the changes when an event occurs.


1 Answers

To answer your specific question of "How do you invoke a TkInter event from a separate object", use the event_generate command. It allows you to inject events into the event queue of the root window. Combined with Tk's powerful virtual event mechanism it becomes a handy message passing mechanism.

For example:

from tkinter import *

def doFoo(*args):
    print("Hello, world")

root = Tk()
root.bind("<<Foo>>", doFoo)

# some time later, inject the "<<Foo>>" virtual event at the
# tail of the event queue
root.event_generate("<<Foo>>", when="tail")

Note that the event_generate call will return immediately. It's not clear if that's what you want or not. Generally speaking you don't want an event based program to block waiting for a response to a specific event because it will freeze the GUI.

I'm not sure if this solves your problem though; without seeing your code I'm not sure what your real problem is. I can, for example, access methods of root in the constructor of an object where the root is passed in without the app locking up. This tells me there's something else going on in your code.

Here's an example of successfully accessing methods on a root window from some other object:

from tkinter import *

class myClass:
    def __init__(self, root):
        print("root background is %s" % root.cget("background"))

root = Tk()
newObj = myClass(root)
like image 126
Bryan Oakley Avatar answered Sep 28 '22 06:09

Bryan Oakley