解决方案!
问题是,如果您在与 tk 线程不同的线程中从 Python 的 raw_input 读取数据,则 tk 会崩溃!
一个演示这个问题的小程序在这里。如果你运行它,它会很高兴地从第二个线程获得键盘输入——直到你输入命令“tk”,它会打开一个空的 tk 窗口。你可以用那个窗口做任何你喜欢的事情——直到你在控制台窗口中输入并按下回车键,当整个程序崩溃时。
为什么我在不是主线程的线程中从 raw_input 读取?
我的程序是一个控制台应用程序,但我控制着许多不同的部分,其中之一是 pi3d OpenGL ES 2.0 图形库,它必须以或接近主 Python 线程的帧速率进行更新。
如何解决它?
足够“简单” - 注册 tk 菜单事件并直接获取密钥!除了这是一个糟糕的解决方案,因为您必须模拟控制台已经为您所做的所有事情——删除、左右箭头和诸如此类的事情。但这就是我必须做的。
该程序是否应该成为一个成熟的传统知识应用程序?
但我不能那样做——这个程序的全部意义在于你可以通过终端窗口运行它——经常连接到无头机器。坦率地说,我更有可能把它变成一个诅咒程序!
tk 窗口只是整个事情的一小部分 - 如果您没有连接硬件(或者不想一直在脸上闪烁),那么它只是一个在开发时显示模拟灯的窗口。我不会尝试在无头机器上使用它,这很好。
这是一个错误吗?
我总是不愿意在不是我自己的软件上贴上这样的标签,但我很难想出任何其他描述。它会导致崩溃,并且该崩溃不会产生任何类型的有用信息。我认为 Tkinter 在从不同线程调用时简单地崩溃有点蹩脚,但至少记录了这种行为(如果你深入研究的话) - 在这种情况下,我正在调用 Python 内置,所以我没有基于期望它会与这个库进行交互,并且没有关于这个问题的文档。
有没有办法解决?
我有点希望有一个解决方法——这个单页程序是一长串功能中的一个项目,现在变成了一整天令人头疼的调试会议,我不想这样做至少在此之后再扔一天,因为这段时间实际上都没有产生新功能。
最好的情况是,如果 tk 团队承认这是一个错误并提出了修复方案。但我不希望在一年后在我的桌面上...
所以也许真正最好的事情是如果有某种方法可以让 tk 简单地忽略键盘,而不是崩溃。我用 tk 的“忙”做了一个小实验,但这没有用,而且似乎不是正确的事情。
稍后,我现在正在考虑将照明作为一个独立的程序运行,一个使用 Python 的子进程库的单独子进程,并通过标准输入向它发送文本命令。如果这是唯一正在解决的问题,这将是矫枉过正,但事实上
知道了。
用 sys.stdin.readline() 替换 raw_input() 就可以了——至少在演示中(我更新了)。随意下载并自己尝试!
我希望这可以节省其他人的时间。