概述
tkinter.simpledialog中的askstring()是个很方便的方法,str=askstring(root,title,prompt)就可以使用弹出信息窗口询问并获得字符串,大部分情况下它都工作得很好,但在多线程的情况下莫名的问题就来了:
- 弹出的窗口无法点击
- 抛出‘TclError: window ".34672232" was deleted before its visibility changed’错误
而且情况很严重,linux下3次有一次问题,win下几乎就是不可用的,本来挺好用的方法变得无比麻烦。
查看源码可发现,该方法最终的实现是通过创建一个Toplevel()窗口 (tkinter中一个窗口控件,虽然是一个独立窗口但又依赖于根窗口不能独立存在) 建立的对话框:
<pre class="brush: python;"> class Dialog(Toplevel): def __init__(self, parent, title = None): Toplevel.__init__(self, parent) </pre>
而在默认没有指定父控件的情况下会使用默认的根窗口进行初始化:
<pre class="brush: python;"> if not parent: parent = tkinter._default_root </pre>
既然在主线程的调用工作的很好,而子线程调用就出问题,很可能就是多线程冲突的问题,那解决办法就很简单了:将调用到主线程的东西(根窗口对象)改为new一个新的根窗口传给Toplevel,但同时由于这个新窗口我们其实并不想要看到它,所以还需要让它不可见,并且及时销毁:
<pre class="brush: python;"> t_root = tk.Tk() t_root.withdraw() str = askstring(parent=t_root, title='title', prompt="message") t_root.destroy() </pre>
测试可行,简单的方法又变得简单可靠了
转载于:https://my.oschina.net/yumenokanata/blog/385045
最后
以上就是高贵鸵鸟为你收集整理的[tkinter]在非主线程中调用askstring()方法出错的解决方案的全部内容,希望文章能够帮你解决[tkinter]在非主线程中调用askstring()方法出错的解决方案所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复