«GUI перестает отвечать на запросы после нажатия кнопки» - PullRequest
1 голос
/ 29 марта 2019

Я разработал графический интерфейс для своего приложения и после нажатия кнопки подключил собственную функцию, в которой я вызываю команду bash для одновременного запуска 2 скриптов Python. Оба скрипта являются приложениями Qt. У меня есть кнопка «Пуск» для запуска команды bash. Но как только я нажал кнопку, оба приложения запустились, но мой графический интерфейс завис. Кроме того, у меня есть кнопка «Стоп», чтобы остановить эти приложения, но графический интерфейс зависает, и я не могу ничего сделать с графическим интерфейсом. Что я делаю не так?

Я пробовал разные варианты запуска 2-х сценариев одновременно, но команда python3 script1.py & python3 script2.py & отлично сработала. Есть ли другие пути? os.system() или subprocess.call() не сработали для меня. Есть ли эффективные способы сделать это?

Это мой основной код для моего интерфейса.

class MainApp(QtWidgets.QMainWindow, mainui.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        self.setupUi(self)
        self.exitapp()
        self.startApp()


    def multipleopen(self):
        self.output = subprocess.check_output(['bash', '-c', 
                      "python3 guiGO.py & python3 liveSpectogram.py &"])
    def startApp(self):
        self.start.clicked.connect(self.multipleopen)

    def exitapp(self):
      self.exit.clicked.connect(QtCore.QCoreApplication.instance().quit)

Я ожидаю, что оба приложения запустятся нажатием кнопки «Пуск» и остановятся нажатием кнопки «Стоп». Но после нажатия кнопки «Пуск» графический интерфейс зависает, и я не могу ничего сделать, кроме как закрыть запущенные приложения и закрыть окно графического интерфейса

GUI перестает отвечать на запросы

Я вынужден выйти из GUI

Я должен остановить скрипт вручную, используя кнопку остановки

1 Ответ

2 голосов
/ 29 марта 2019

Функция subprocess.check_output() блокирует, поэтому она не позволит циклу событий графического интерфейса выполнить свою работу, заморозив ваше приложение, вместо этого вы должны использовать QProcess:

class MainApp(QtWidgets.QMainWindow, mainui.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        self.setupUi(self)

        self._process = QtCore.QProcess(self)
        self._process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
        self._process.setProcessChannelMode(QtCore.QProcess.ForwardedChannels)
        self._process.setProgram('bash')
        self._process.setArguments(['-c', 'python3 guiGO.py & python3 liveSpectogram.py &'])

        self.exitapp()
        self.startApp()

    # read prints
    def on_readyReadStandardOutput(self):
        self.output = self._process.readAllStandardOutput()
        print(self.output)

    def startApp(self):
        self.start.clicked.connect(self._process.start)

    def exitapp(self):
        self.exit.clicked.connect(self.close)

Обновление:

Если вы хотите уничтожить скрипты Python, вы должны сделать это с помощью bash, с помощью команды pkill, поскольку именно она запустила их.И в какой части кода вы должны вызывать pkill ?, возможной частью является метод closeEvent.

from PyQt5 import QtCore, QtWidgets

class MainApp(QtWidgets.QMainWindow): #, mainui.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        self.setupUi(self)

        self._scripts = ("guiGO.py", "liveSpectogram.py")
        self._processes = []
        for script in self._scripts:
            process = QtCore.QProcess(self)
            process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
            process.setProcessChannelMode(QtCore.QProcess.ForwardedChannels)
            process.setProgram('bash')
            process.setArguments(['-c', 'python3 {}'.format(script)])
            self._processes.append(process)

        self.exitapp()
        self.startApp()

    # read prints
    def on_readyReadStandardOutput(self):
        self.output = self.sender().readAllStandardOutput()
        print(self.output)

    def startApp(self):
        for process in self._processes:
            self.start.clicked.connect(process.start)

    def exitapp(self):
        self.exit.clicked.connect(self.close)

    def closeEvent(self, event):
        for script in self._scripts:
            QtCore.QProcess.startDetached("bash", ["-c", "pkill -f {}".format(script)])
        super(MainApp, self).closeEvent(event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainApp()
    w.show()
    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...