1

我正在尝试在 Tkinter 中使用withdraw()/deiconify() 为我的应用程序进行隐藏/显示,但是在 deiconify() 方法调用后我的应用程序挂起。在 Win7 上运行此代码。我做错了什么?

import Tkinter as tk
import threading


class MyApp(object):
    def __init__(self, parent):
        self.root = parent
        self.root.geometry('400x300')
        self.root.title('My Application')

        btn = tk.Button(parent, text='Hide', command=self.onClick)
        btn.pack()

    def onClick(self):
        self.hide()
        self.t = threading.Timer(3, self.show)
        self.t.start()

    def hide(self):
        print 'hide()'
        print 'state: ', self.root.state()
        print 'withdraw()'
        self.root.withdraw()
        print 'state: ', self.root.state()

    def show(self):
        print 'show()'
        print 'state: ', self.root.state()
        print 'deiconify()'
        self.root.deiconify()
        print 'state: ', self.root.state()
        print 'show end'

if __name__ == '__main__':
    root = tk.Tk()
    app = MyApp(root)
    root.mainloop()

UPD:有一个工作样本:

import Tkinter as tk
import sched
import time


class MyApp(object):
    def __init__(self, parent):
        self.root = parent
        self.root.geometry('400x300')

        btn = tk.Button(parent, text='Hide', command=self.onClick)
        btn.pack()

        self.scheduler = sched.scheduler(time.time, time.sleep)

    def onClick(self):
        self.hide()
        self.scheduler.enter(3, 1, self.show, ())
        self.scheduler.run()

    def hide(self):
        self.root.withdraw()

    def show(self):
        self.root.deiconify()

if __name__ == '__main__':
    root = tk.Tk()
    app = MyApp(root)
    root.mainloop()
4

1 回答 1

1

Tkinter 不是线程安全的,您是self.root.deiconify()从线程调用的。这很可能是您问题的根源。您必须重新设计您的解决方案,让线程使用线程安全队列来请求主循环调用 Tkinter。

您可以在不使用线程的情况下使用 Tkinter 做很多事情。你确定你需要它们吗?

于 2012-10-29T11:16:23.317 回答