python - 替代 tkinter.dooneevent

标签 python c++ python-3.x tkinter tk-toolkit

我正在将一个用 C++ 编写并嵌入了 Python 和 TCL 解释器的程序(VMD,Visual Molecular Dynamics)移植到 Python 3.x。它的大部分 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 已从 Python 3 中删除,我找不到它的替代品。我尝试调用低级 Tcl_DoOneEvent(TCL_DONT_WAIT) 但是当我动态创建一个新窗口时,我最终导致 Python 解释器崩溃并出现错误 Fatal Python error: PyEval_RestoreThread: NULL tstate.

tkinter woes when porting 2.x code to 3.x, 'tkinter' module attribute doesn't exist 中的答案没有帮助,因为我没有用户可能创建的所有窗口的列表。

在这种情况下,有人对如何刷新 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.

现在,我不知道如何将它准确地转换成您的代码 - 您是否有一个可以访问 dooneevent 的根 Tk 对象?我对 python 2 tkinter 一点也不熟悉,所以我不知道我的代码与你的代码映射的准确程度。但是,我在做与您非常相似的事情时发现了这一点——试图将 tkinter 事件循环集成到 asyncio 事件循环中。我能够创建一个在循环中调用此方法的协程,每次都让步(偶尔休眠),以便 GUI 保持响应,而不会使用 tkinter._tkinter.create() 阻塞异步事件循环>.

@asyncio.coroutine
def update_root(root):
    while root.tk.dooneevent(tkinter._tkinter.DONT_WAIT):
        yield

编辑:我刚刚阅读了您关于没有小部件的评论。我知道 root.tk 对象是通过调用 tkinter._tkinter.create 创建的 tkinter._tkinter.TkappType 实例,但我不知道不要认为它是全局性的。我很确定它是核心 Tcl 解释器。您可以通过调用 create 创建您自己的。虽然没有记录,但您可以在 tkinter.Tk.__init__

中查看它的用法

关于python - 替代 tkinter.dooneevent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28934079/

相关文章:

python - tkinter:在父级中显示的 Toplevel 中的框架

python - `pd.concat` 与 `join==' 内部 '` 不会产生 Pandas 数据帧的交集

python - 如何更改 PyQt 或 PySide 中的最小化事件行为?

python - 找不到gunicorn命令,但它在我的requirements.txt中

c++ - OpenGL为什么会给我错误:错误:0:1: '':不支持 '330'版本?

c++ - 只是一些简单的错误

c++ - 重用的boost ptree是否需要清除?

适用于 Mac 的 Python Winsound 等效项

python - 删除 Python 双链表中的节点时遇到问题

python - Django:在信号中获取 m2m 相关对象