【发布时间】:2014-08-09 04:16:55
【问题描述】:
我目前正在为neovim 实现一个示例 UI, 并决定使用 Tkinter/python 由于流行/简单 平台。我遇到的问题是 tkinter 似乎“堆叠” 当窗口高度超过某个阈值时,UI 会更新。
Here 是一个显示问题的视频。
右边的窗口是运行neovim的终端模拟器,左边的 window 是连接到它的 Tkinter UI 程序。这个想法是 tkinter UI 应该镜像 neovim 终端屏幕,包括 方面。在这个视频中,永远不要把注意力从 终端窗口,因此 Tk 必须处理的唯一事件来自 连接到 neovim(描述屏幕的虚拟“nvim”事件 更新)
视频的第一部分显示,当 窗口高度很小,但是当我增加时开始滞后更新 高度。
Here 是 Tkinter 程序的代码。虽然 neovim API 非常新并且仍在大量开发中(代码可能对某些读者没有意义),但我认为我要解决的问题接近实现终端 模拟器(使用 Tk 文本小部件):它必须有效地处理大量格式化文本更新。
我在 GUI 编程方面非常缺乏经验。 Tkinter 是一个明智的选择吗? 这个任务?如果是,那么有人可以提示我做错了什么吗?
解释一下发生了什么:Neovim API 是线程安全的,vim.next_event() 方法会阻塞(不忙等待,它使用下面的 libuv 事件循环)直到收到事件。
当vim.next_event() 调用返回时,它会使用generate_event 通知Tkinter 线程,该线程将执行实际的事件处理(它还缓冲redraw:start 和redraw:stop 之间的事件以优化屏幕更新)。
所以实际上有两个事件循环并行运行,后台事件循环以线程安全的方式提供 Tkinter 事件循环(generate_event 方法是少数可以从其他线程调用的方法之一)
【问题讨论】:
-
您知道,Tk 仅在事件循环空闲时更新绘图? (例如,当
after idle触发时)。您可能只是简单地用许多事件淹没事件循环,因此重绘仅在突发过去后发生。除此之外,您人为地将 Queue 对象的大小限制为 1,因此使用 python 糟糕的线程,您需要在各处支付大量线程更改成本。
标签: python user-interface tkinter tk neovim