退出input() / raw_input()后终端状态异常(文本不可见/无回显)
我正在用Python 3写一个小工具应用程序(下面的测试案例在Python 2中也能运行),并使用PyQt 4来创建一个可以和Qt窗口互动的REPL提示符。
不过,我遇到了一个解决不了的问题:当我在应用程序中使用exit()
退出时,如果code
模块正在执行input()
(在Python 2.x中叫raw_input()
),我的Linux终端就不再显示我输入的字符了。也就是说,终端似乎处于一种坏掉的状态,可能是因为input()
发出了一些转义序列。
我尝试了很多方法来解决这个问题,包括使用curses
模块和其他方法在运行exit
之前重置终端,甚至尝试模拟stdin
流来通过实际将exit()
传递给input()
来退出(不幸的是,code.InteractiveConsole.push()
并不是像人们想的那样工作),还尝试用threading
写一个自己的非阻塞input()
,但都没有成功。
最后,这里有一个简化的测试案例来演示这个问题:
#!/usr/bin/env python3
import code
import sys
from PyQt4.QtGui import QApplication, QWidget
app = QApplication(sys.argv)
app.lastWindowClosed.connect(exit)
widget = QWidget()
widget.show()
code.interact()
对于不熟悉(Py)Qt的人来说,这个程序会打开一个空白窗口,当窗口关闭时,app
的lastWindowClosed
信号会触发内置的exit()
函数。这发生在code
模块正在执行input()
来从sys.stdin
读取输入的时候。而在这里,当我关闭窗口后,终端中输入的字符都不显示了。
我主要使用Python 3,实际的应用程序使用的是Python 3特有的代码,但我也在Python 2.7中尝试了这个测试案例,结果显示同样的问题。
4 个回答
来自 Quentin Engles 的回答对我也有帮助,但作为一个刚接触Python的新手,我不太明白 stty sane
应该放在哪里。在经过一番寻找和思考后,我明白了 exit 是指 exit()
这个方法,所以我创建了一个叫 exiting()
的方法,并传递了一个引用给它:
#!/usr/bin/env python3
import code
import sys
from PyQt4.QtGui import QApplication, QWidget
def exiting():
os.system('stty sane')
exit()
app = QApplication(sys.argv)
app.lastWindowClosed.connect(exiting)
widget = QWidget()
widget.show()
code.interact()
这并不是解决问题的真正办法,但如果你在关闭应用程序后,在终端里输入“reset”,它就会恢复正常。
我之前在开发一个C语言应用时也遇到过类似的问题,因为它没有正确关闭一个管道。也许这里发生的情况也有点像。
试试这个命令 os.system('stty sane')
。这个 stty sane
命令是用来重置一些设置的,比如让屏幕上的输出恢复正常,听说还有其他一些作用。