【问题标题】:is Tk().withdraw() suitable to run from a thread?Tk().withdraw() 是否适合从线程运行?
【发布时间】:2013-05-06 12:31:29
【问题描述】:

我正在我的 python 应用程序中实现一个剪贴板监视器。如果复制的文本满足某些要求,我想向用户显示一个对话框。如果用户点击“是”我想触发一个功能 - 在这种情况下 webui.app.add_internal(cb) 。如果用户选择“否”,我想每隔 3 秒检查一次剪贴板是否有更改。

一切似乎都运行良好,但这段代码并没有像我预期的那样不停地重复运行。稍微调查一下表明Tk().withdraw() 似乎是有问题的行。尽管没有它,Tk 的主要空白窗口将出现在显示的对话框旁边,并且用户的最后选择似乎会被记住以供以后使用(这是不希望的)。

考虑以下代码:

import pyperclip
import tkMessageBox, Tkinter
import threading

cbOld = "notAurl"
def catchClipboardChange():
global cbOld
cb = pyperclip.paste()
Tkinter.Tk().withdraw()
if (cb != cbOld):
    #Change in clipboard detected. Analize!
    if (urlValidation(cb) and isDownloadExt(cb) and tkMessageBox.askyesno("Start downloading?","Do you want to start downloading {}".format(cb))):
        webui.app.add_internal(cb)
    cbOld = cb # Old clipboard update
threading.Timer(3.0,catchClipboardChange).start()

catchClipboardChange();

有什么建议可以做得更好吗?我正在考虑如何在不需要撤销方法的情况下显示对话框,或者更安全地使用线程。感谢任何帮助

【问题讨论】:

    标签: python python-2.7 tkinter tkmessagebox


    【解决方案1】:

    不,您不能从主线程以外的其他线程调用withdraw()。

    【讨论】:

    • 这是为什么呢?那么你会如何建议呢?
    • @user1555863:为什么?这就是它的设计方式;您只能在创建它的同一线程中调用小部件的函数。您需要设置一个线程安全队列,您可以在其中发布对主线程的请求,然后从主线程轮询队列并执行请求。
    • 谢谢。你能举例说明这是如何在某处完成的吗?
    • @user1555863:这个网站上有几个例子,稍微搜索一下。这是一个使用 Tkinter 和队列的答案,尽管目的不同:stackoverflow.com/a/14381671/7432
    猜你喜欢
    • 1970-01-01
    • 2022-01-09
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多