Tkinter: invoke event in main loop

By : Mark

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.

By : Mark


Here below just some doc and link to better understand Bryan's answer above.

function description from New Mexico Tech :

w.event_generate(sequence, **kw)

This method causes an event to trigger without any external stimulus. The handling of the event is the same as if it had been triggered by an external stimulus. The sequence argument describes the event to be triggered. You can set values for selected fields in the Event object by providing keyword=value arguments, where the keyword specifies the name of a field in the Event object.

list and description of tcl/tk event attributes here

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)

One idea is you could use wceload:

Write a cab file that has a custom step (I think you might need to create a setup.dll) that will delete your application.

Get your application to call wceload when it exits to run this cab, passing the argument for wce load to delete the cab after it's finished running.

Not very slick I know.

This video can help you solving your question :)
By: admin