Tkinter:在主循环中调用事件

22 投票
2 回答
30695 浏览
提问于 2025-04-11 09:34

我想知道怎么从一个单独的对象里调用 tkinter 的 event

我希望能找到类似 wxWidgets 里的 wx.CallAfter 的方法。例如,如果我创建了一个对象,并把我的 Tk 根实例传给它,然后试图从我的对象里调用那个根窗口的方法,我的应用程序就会卡住。

我想到的最好办法就是使用 after 方法,然后从我的单独对象里检查状态,但这样似乎有点浪费。

2 个回答

7

下面是一些文档和链接,可以帮助更好地理解Bryan上面的回答。

这是来自新墨西哥科技大学的函数描述:

w.event_generate(sequence, **kw)

这个方法可以让一个事件在没有外部刺激的情况下被触发。处理这个事件的方式就像是它是由外部刺激引发的一样。这里的sequence参数描述了要触发的事件。你可以通过提供keyword=value的方式来设置Event对象中某些字段的值,其中keyword指定了Event对象中字段的名称。

关于tcl/tk事件属性的列表和描述可以在这里找到。

41

要回答你关于“如何从一个独立对象调用TkInter事件”的问题,可以使用event_generate命令。这个命令可以让你把事件放入主窗口的事件队列中。结合Tk的强大虚拟事件机制,它就成了一种方便的消息传递方式。

举个例子:

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")

需要注意的是,event_generate这个调用会立即返回。是否这样做符合你的需求还不太清楚。一般来说,你不希望基于事件的程序在等待特定事件的响应时被阻塞,因为这样会导致界面卡死

不过,我不确定这是否能解决你的问题;如果不看到你的代码,我也不太清楚你真正的问题是什么。例如,我可以在一个对象的构造函数中访问根窗口的方法,而不会导致应用程序锁死。这让我觉得你的代码中可能还有其他问题。

下面是一个成功从其他对象访问根窗口方法的例子:

from tkinter import *

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

root = Tk()
newObj = myClass(root)

撰写回答