Не удается обновить QTextEdit в многопроцессорном режиме - PullRequest
1 голос
/ 17 января 2020

Я пытаюсь подключить файл и выводить его непрерывно в поле QTextEdit. Тем не менее, мой подпроцесс и выход расположены в многопроцессорном режиме. Вот мой код:

shouldRun = True
wMain = QtGui.QWidget()
textboxSideA = QtGui.QTextEdit(wMain)

def tailLog():
    subA = subprocess.Popen(["tail", "-F", "<FILENAME>", stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=os.setsid)
    pollA = select.poll()
    pollA.register(subA.stdout)

    while shouldRun:
        if pollA.poll(1):
            textboxSideA.append(subA.stdout.readline())
    subA.kill()
    os.killpg(subA.pid, signal.SIGKILL)
    return

processSideA = multiprocessing.Process(target = tailLog)
processSideA.start()

wMain.show()

, когда вызывается textboxSideA.append, текстовое поле ничего не показывает. Я попытался просто добавить к нему прямую строку, чтобы убедиться, что это не моя readline, которая была плохой. Однако это не проблема. Затем я попытался распечатать мою readline напрямую в терминал, используя print(subA.stdout.readline()), который работал нормально. Поэтому я пришел к выводу, что текстовое поле QTextEdit GUI не обновляется. Я перепробовал все, и даже Google не дал мне ответа. Кроме того, я могу ввести текстовое поле, и оно отображается правильно, и я могу сохранить то, что я набрал. Моему GUI просто не нравится многопроцессорность, так как я могу вызвать .append() вне многопроцессора, и он прекрасно работает.

1 Ответ

1 голос
/ 17 января 2020

Qt не поддерживает многопроцессорность, поэтому опасно обновлять GUI из другого процесса, GUI можно и нужно обновлять только из потока процесса, в котором он был создан.

Вкл с другой стороны, в этом случае нет необходимости использовать многопроцессорность, поскольку вы можете использовать QProcess:

import sys

from PyQt4 import QtCore, QtGui


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.process = QtCore.QProcess(self)
        self.process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
        self.textedit = QtGui.QTextEdit()

        self.setCentralWidget(self.textedit)

    def tail(self, filename):
        self.process.kill()
        self.process.start("tail", ["-F", filename])

    @QtCore.pyqtSlot()
    def on_readyReadStandardOutput(self):
        msg = self.process.readAllStandardOutput().data().encode()
        self.textedit.append(msg)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.tail("<FILENAME>")
    w.show()
    sys.exit(app.exec_())
...