Терминал в сломанном состоянии (невидимый текст/без эха) после выхода() во время ввода()/raw_input()

Я писал небольшое приложение-утилиту, использующее Python 3 (однако тестовый файл также работает в Python 2, однако) и PyQt 4, который использует модуль code, чтобы вызвать приглашение REPL, позволяющее взаимодействовать с окном Qt.

К сожалению, я столкнулся с проблемой, которую мне не удалось решить: когда я exit() приложение, а code находится внутри input() (известный как raw_input() в Python 2.x), мой Linux-терминал впоследствии больше не повторяет введенные символы. То есть терминал, по-видимому, остается в сломанном состоянии, предположительно из-за некоторой escape-последовательности, выданной input().

Я испробовал множество подходов, чтобы исправить это, от использования модуля curses и других средств до reset терминала до запуска exit, чтобы попытаться эмулировать поток stdin для выхода на самом деле передача exit() для ввода() (без сожаления code.InteractiveConsole.push() не работает так, как можно было бы подумать), чтобы попытаться написать мой собственный неблокирующий input() с помощью threading, но я был неспособность свести что-то работающее.

Здесь, здесь, здесь и здесь являются дискуссиями подобных проблем.

Наконец, здесь приведено тестовое задание для демонстрации проблемы:

#!/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, и он показывает ту же проблему.

Ответы

Ответ 1

Это не реальное решение проблемы, но если вы наберете "reset" в терминале после того, как вы закрыли приложение, оно вернется к нормальному.

У меня были подобные проблемы один раз при разработке приложения c, которое не закрывало канал правильно. Возможно, что-то подобное происходит и здесь.

Ответ 2

Попробуйте os.system('stty sane'). Предполагается, что stty sane reset эхо и некоторые другие вещи.

Ответ 3

Ответ от Quentin Engles работал у меня тоже, но как неофит Питона я не понимал, куда должен был идти stty sane. После некоторой охоты и царапин на голове я понял, что выход был ссылкой на метод 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()

Ответ 4

Я столкнулся с той же проблемой, используя модуль curses. Используя другой ответ на этой странице, я обошел проблему с import os в начале программы, а затем закончил программу с помощью os.system('reset').