代替tkinter.dooneevent 我正在移植一个程序(VMD,Visual Maple Dyrimes),它是用C++编写的,并且既有Python和Tcl解释程序,也有Python 3。它的大部分UI是使用TCL/TK框架和OpenGl硬编码的,因此UI刷新是手动完成的。当Python解释器运行时,可以使用Tkinter动态创建新窗口,甚至向主UI添加新菜单。在这种情况下,所有TK事件都是通过定期调用Python端的一些代码来刷新的(见下文)。这确保了所有更新都是线程安全的,并且不会破坏解释器 int PythonTextInterp::doTkUpdate() { // Don't recursively call into dooneevent - it makes Tkinter crash for // some infathomable reason. if (in_tk) return 0; if (have_tkinter) { in_tk = 1; int rc = evalString( "import Tkinter\n" "while Tkinter.tkinter.dooneevent(Tkinter.tkinter.DONT_WAIT):\n" " pass\n" ); in_tk = 0; if (rc) { return 1; // success } // give up have_tkinter = 0; } return 0; }
但是,函数代替tkinter.dooneevent 我正在移植一个程序(VMD,Visual Maple Dyrimes),它是用C++编写的,并且既有Python和Tcl解释程序,也有Python 3。它的大部分UI是使用TCL/TK框架和OpenGl硬编码的,因此UI刷新是手动完成的。当Python解释器运行时,可以使用Tkinter动态创建新窗口,甚至向主UI添加新菜单。在这种情况下,所有TK事件都是通过定期调用Python端的一些代码来刷新的(见下文)。这确保了所有更新都是线程安全的,并且不会破坏解释器 int PythonTextInterp::doTkUpdate() { // Don't recursively call into dooneevent - it makes Tkinter crash for // some infathomable reason. if (in_tk) return 0; if (have_tkinter) { in_tk = 1; int rc = evalString( "import Tkinter\n" "while Tkinter.tkinter.dooneevent(Tkinter.tkinter.DONT_WAIT):\n" " pass\n" ); in_tk = 0; if (rc) { return 1; // success } // give up have_tkinter = 0; } return 0; },python,c++,python-3.x,tkinter,tk,Python,C++,Python 3.x,Tkinter,Tk,但是,函数tkinter.dooneevent已从Python3中删除,我找不到替代它的函数。我尝试调用低级的Tcl\u DoOneEvent(Tcl\u DONT\u WAIT)但是当我动态创建一个新窗口时,我最终导致Python解释器崩溃,错误为致命的Python错误:PyEval\u RestoreThread:NULL tstate @asyncio.coroutine def update_root(root): while root.tk.dooneevent(tkinter
tkinter.dooneevent
已从Python3中删除,我找不到替代它的函数。我尝试调用低级的Tcl\u DoOneEvent(Tcl\u DONT\u WAIT)
但是当我动态创建一个新窗口时,我最终导致Python解释器崩溃,错误为致命的Python错误:PyEval\u RestoreThread:NULL tstate
@asyncio.coroutine
def update_root(root):
while root.tk.dooneevent(tkinter._tkinter.DONT_WAIT):
yield
中的答案没有帮助,因为我没有用户可能创建的所有窗口的列表
在这种情况下,有人对如何刷新TK事件有什么建议吗?它可以是Python端,也可以是C++。
提前感谢看起来这相当于:
root = tkinter.Tk()
# Here's your event handler. Put it in a loop somewhere.
root.tk.dooneevent(tkinter._tkinter.DONT_WAIT)
# I don't know if it's possible to access this method without a Tk object.
现在,我不知道如何准确地将其转换为您的代码-您是否有根Tk对象,可以使用它访问dooneevent
?我对Python2Tkinter一点也不熟悉,所以我不知道我的代码与您的代码的映射有多均匀。然而,我在做与您非常相似的事情时发现了这一点—尝试将tkinter
事件循环集成到asyncio
事件循环中。我能够创建一个在循环中调用此方法的协同程序,每次都会产生响应(偶尔会休眠),这样GUI就可以保持响应,而不会使用tkinter.\u tkinter.create()
阻塞异步IO事件循环
编辑:我刚读到你关于没有小部件的评论。我知道
root.tk
对象是一个tkinter.\u tkinter.TkappType
实例,它是通过调用tkinter.\u tkinter.create
创建的,我认为它不是全局的。我很确定这是Tcl的核心解释器。您可以通过调用create
来创建自己的。虽然它没有文档记录,但是您可以在tkinter.Tk.\uu init\uuuuu
中查看它的用法,而不是刷新所有事件(在Python端),您可以在空闲(,*args)之后使用tkinter通用小部件方法
让它告诉你系统什么时候空闲,什么时候不再处理事件?@martineau问题是UI是用C++/TCL/TK构建的,所以在Python中没有任何小部件可以在空闲后调用它的。此外,程序不允许从任何Python脚本中调用mainloop
,否则它将停止响应。