Skip to content Skip to sidebar Skip to footer

Executing A Pyqt5 Gui Which Includes Subprocesses From The Linux Terminal Causes A Black Screen In The Gui And Freezes It

First, I would like to show you what works so far. Below is a simple GUI built with the same principles as the one that causes problems. It has a button and when you click it a cou

Solution 1:

You should not use Popen since the communicate() method is blocking, instead use QProcess:

#!/usr/bin/python3.5from PyQt5 import QtCore, QtWidgets


classGUI(QtWidgets.QWidget):
    def__init__(self, parent=None):
        super().__init__(parent)
        self.initGUI()
        self.behaviours()

    definitGUI(self):
        self.button = QtWidgets.QPushButton("Button")
        self.label = QtWidgets.QLabel()

        box = QtWidgets.QVBoxLayout(self)
        box.addWidget(self.button)
        box.addWidget(self.label)

        self.show()

    defbehaviours(self):
        self._onedrive_process = QtCore.QProcess(self)
        self._onedrive_process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        self._onedrive_process.readyReadStandardOutput.connect(
            self.on_readyReadStandardOutput
        )
        self._onedrive_process.setProgram("onedrive")

        self.button.clicked.connect(self.connect_to_onedrive)

    @QtCore.pyqtSlot()defconnect_to_onedrive(self):
        self._onedrive_process.start()

    @QtCore.pyqtSlot()defon_readyReadStandardOutput(self):
        result = self._onedrive_process.readAllStandardOutput()
        print(result)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ex = GUI()
    sys.exit(app.exec_())

Update:

If you want to pass options to the command you must use setArguments():

from PyQt5 import QtCore, QtGui, QtWidgets


classOneDriveManager(QtCore.QObject):
    logChanged = QtCore.pyqtSignal(str)

    def__init__(self, parent=None):
        super().__init__(parent)
        self._process = QtCore.QProcess(self)
        self._process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
        self._process.setProgram("onedrive")

    deflaunch(self, options=None):
        self._process.setArguments(options)
        if self._process.state() != QtCore.QProcess.NotRunning:
            self._process.kill()
        self._process.start()

    defhelp(self):
        self.launch(["--help"])

    defsynchronize(self):
        self.launch(["--synchronize"])

    @QtCore.pyqtSlot()defon_readyReadStandardOutput(self):
        res = self._process.readAllStandardOutput().data().decode()
        self.logChanged.emit(res)


classWidget(QtWidgets.QWidget):
    def__init__(self, parent=None):
        super().__init__(parent)

        self._onedrive_manager = OneDriveManager(self)

        help_button = QtWidgets.QPushButton("Help")
        help_button.clicked.connect(self._onedrive_manager.help)

        synchronize_button = QtWidgets.QPushButton("Synchronize")
        synchronize_button.clicked.connect(self._onedrive_manager.synchronize)

        log_plaintextedit = QtWidgets.QPlainTextEdit()
        self._onedrive_manager.logChanged.connect(log_plaintextedit.setPlainText)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(help_button)
        lay.addWidget(synchronize_button)
        lay.addWidget(log_plaintextedit)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = Widget()
    w.show()

    sys.exit(app.exec_())

Post a Comment for "Executing A Pyqt5 Gui Which Includes Subprocesses From The Linux Terminal Causes A Black Screen In The Gui And Freezes It"