使用 Python Tk 作为线程代码的前端

发布于 2024-11-26 12:22:01 字数 1044 浏览 1 评论 0原文

我知道Python的Tk接口在使用线程时存在一些问题,并且我已经遇到了问题。我现在的想法是使用 Queue.Queue 以某种方式将事件传递到 Tk 主循环,类似于以下示例。

from Tkinter import *
import Queue
import time

# this queue will be filled by other threads
queue = Queue.Queue()
queue.put("Helloooo!")
queue.put("hi there, everyone!")

class Application(Frame):
    def update(self):
        while True:
            try:
                text = queue.get(False)
                self.hi_there["text"] = text
                time.sleep(3)
            except Queue.Empty:
                self.quit()

    def create_widgets(self):
        self.hi_there = Label(self)
        self.hi_there["text"] = "Hello"

        self.hi_there.pack({"side": "left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.create_widgets()

root = Tk()
app = Application(master=root)
app.update()
app.mainloop()

当然,我不能自己调用​​ update (这将在 UI 显示之前执行所有操作),但需要 Tk 在其主循环期间处理它。

有没有一种万无一失的方法可以用 Tk 来实现这一点,并且在某些情况下不会崩溃?或者我应该求助于 Qt 呢?

I know that Python’s Tk interface has some problems when using threads, and I’ve already run into problems with it. My idea is now to use a Queue.Queue to somehow pass events to the Tk mainloop, similarly to the following example.

from Tkinter import *
import Queue
import time

# this queue will be filled by other threads
queue = Queue.Queue()
queue.put("Helloooo!")
queue.put("hi there, everyone!")

class Application(Frame):
    def update(self):
        while True:
            try:
                text = queue.get(False)
                self.hi_there["text"] = text
                time.sleep(3)
            except Queue.Empty:
                self.quit()

    def create_widgets(self):
        self.hi_there = Label(self)
        self.hi_there["text"] = "Hello"

        self.hi_there.pack({"side": "left"})

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.create_widgets()

root = Tk()
app = Application(master=root)
app.update()
app.mainloop()

Of course, I must not call update myself (this will execute everything before the UI is even shown) but need Tk to handle that during its mainloop.

Is there any foolproof way to accomplish that with Tk which will not break under certain circumstances? Or should I just resort to Qt for that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

骷髅 2024-12-03 12:22:01

作为一般经验法则,GUI 应用程序永远不应该调用 sleep,永远不应该有无限循环(事件循环除外),并且永远不应该调用“update”。从不调用 update 的唯一例外是,只有当您真正理解为什么不应该调用 update 时才可以。

创建一个执行两件事的方法:检查队列,然后使用“after”在一段时间后调用自身。然后,在所有其他初始化完成之后,在程序开始时、启动事件循环之前调用此方法一次。

有关此类函数的工作示例,请参阅 如何使用 tkinter 创建计时器?

As a general rule of thumb a GUI application should never, ever call sleep, should never have an infinite loop (except for the event loop), and you should never call 'update'. The only exception to never calling update is that is is ok only when you truly understand why you should not.

Create a method that does two things: check the queue, and then use 'after' to call itself after some small period of time. Then, call this method once at the beginning of your program just before starting the event loop, after all other initialization has taken place.

For a working example of such a function, see How to create a timer using tkinter?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文