使用Qt运行日志流送器时Python崩溃 [英] Python crashes when running a log streamer using Qt

查看:100
本文介绍了使用Qt运行日志流送器时Python崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个进程在运行时登录文件(realtime.log),并且我想实时打印应用程序中该文件的每一行.换句话说,我想将输出从流程重定向到GUI.这意味着我正在运行两个不同的进程:引擎"和GUI.

I have a process that logs on a file (realtime.log) while running and I want to print every new line of that file in my application in realtime. In other words I want to redirect the output from the process to the GUI. This means that I have two different processes running: the "engine" and the GUI.

我已经通过使用 Tkinter 实现了这一点,但由于我必须制作一个更复杂、更专业和更美观的 GUI,我决定改用 Qt for Python (PySide2).

I have already achieved this by using Tkinter but since I have to make a more complex, professional and good looking GUI I decided to switch to Qt for Python (PySide2).

Python 经常崩溃: Python已停止工作.窗口开始打印线条,并在某些时候停止工作.

Python often crashes when I launch the GUI with the error message: Python has stopped working. The window starts printing the lines and at some point it stops working.

经过多次尝试和搜索,我发现只有在单击GUI窗口时程序才会崩溃.而且,程序不会突然崩溃,而是在引擎执行结束时崩溃.

After many attempts and searches I got to a point where the program only crashes if I click on the GUI window. Moreover, the program doesn't crash suddenly but it crashes at the end of the engine's execution.

  • Windows 10
  • Python 3.6.5
  • PySide2 5.12.6

请注意,这是简化版本.

Note that this is a simplified version.

datalog_path = "realtime.log"


def get_array_from_file(file_path):
    try:
        with open(file_path, 'r') as file:
            lines = file.readlines()
        return lines
    except:
        print('error in file access')


class Streamer(QRunnable):
    def __init__(self, stream, old_array, edit):
        super().__init__()
        self.stream = stream
        self.old_array = old_array
        self.edit = edit

    def run(self):
        try:
            while self.stream:
                array_file = get_array_from_file(datalog_path)
                if len(array_file) != len(self.old_array):
                    for line in array_file[len(self.old_array) - 1:len(array_file)]:
                        self.edit.append(line)
                        # print(line)
                        self.old_array.append(line)
        except:
            print('problem in streaming funct')


class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()

        self.setWindowTitle("DATALOG")
        self.thread_pool = QThreadPool()
        self.edit = QTextEdit()

        self.stream = True
        self.old_array = get_array_from_file(datalog_path)
        self.streamer = Streamer(self.stream, self.old_array, self.edit)
        self.thread_pool.start(self.streamer)

        window = QWidget()
        layout.addWidget(self.edit)
        window.setLayout(layout)
        self.setCentralWidget(window)


    def closeEvent(self, event):
        self.stream = False
        event.accept()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    app.exec_()

推荐答案

@hyde答案指出了解释原因针对该问题,但其解决方案不适用于PySide2(在PyQt5中必须进行一些小的修改,请参见),另一种方法是创建一个具有以下信号的QObject:

The @hyde answer points out explains the reason for the problem but its solution is not applicable in PySide2 (in PyQt5 a small modification would have to be made, see this), an alternative is to create a QObject that has the signals:

class Signaller(QtCore.QObject):
    textChanged = Signal(str)

class Streamer(QRunnable):
    def __init__(self, stream, old_array):
        super().__init__()
        self.stream = stream
        self.old_array = old_array
        self.signaller = Signaller()

    def run(self):
        try:
            while self.stream:
                array_file = get_array_from_file(datalog_path)
                if len(array_file) != len(self.old_array):
                    for line in array_file[len(self.old_array) - 1:len(array_file)]:
                        self.signaller.textChanged.emit(line)
                        # print(line)
                        self.old_array.append(line)
        except:
            print('problem in streaming funct')

self.stream = True
self.old_array = get_array_from_file(datalog_path)
self.streamer = Streamer(self.stream, self.old_array)
self.streamer.signaller.textChanged.connect(self.edit.append)
self.thread_pool.start(self.streamer)

这篇关于使用Qt运行日志流送器时Python崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆