首次打开时 GUI 崩溃。不过下次打开就正常了

问题描述 投票:0回答:1

我已经使用 python 从 Qt Designer 创建了一个 GUI。该 UI 基本上查询数据库中的数据,将数据(字典列表)转换为对象实例列表,并将它们传递给 UI 的模型。数据有时可能很大或很小。 由于获取大数据可能会使 UI 无响应,因此我使用 QThreadpool.globalinstance 在线程中启动获取任务。我在 QRunnable 中分配了一个名为 task_finished 的信号,该信号连接到插槽,插槽又将转换后的实例传递到我的自定义模型以显示在 QTreeview 中。

我面临的问题是,当我获取小数据时,用户界面按预期工作。但是,如果要获取的数据很大,比如列表中的数据长度约为 635,那么 UI 就会崩溃,而不会出现任何错误或异常。 我可以看到只有 UI 被关闭,但线程在后台运行没有任何问题。 但有时,我会捕获类似 “QThread:线程仍在运行时被销毁”这样的错误。这个错误只发生在我使用QThread的时候。但是使用QThreadpool不会出现这个错误。两者仍然关闭 UI,但线程在后台运行。 这种情况仅在第一次打开 UI 时发生。下一次,它不会崩溃并按预期工作。而且这种行为只发生在我的电脑上。如果我使用笔记本电脑,那么一切都很好。即使上述错误在笔记本电脑上也不会发生。

可能是什么问题?

尝试解决问题的技术 我也尝试使用 QThread,而不是使用 QThreadpool.globalinstance。我遇到错误“QThread:在线程仍在运行时被销毁”是QThread。 尝试了日志记录和调试来查找问题,但仍然找不到任何内容。 当我尝试调试时,我发现每次迭代数据达到计数 50 或 51 时 UI 都会崩溃。我认为 DB 中的数据可能有问题,但即使删除特定数据后,它仍然关闭计数为 50 或 51。此外,如果数据本身有问题,那么 UI 不应该在我的笔记本电脑上工作,对吗?

用我的笔记本电脑检查了我的电脑的配置。 它们之间的主要区别是我的电脑操作系统是 Windows 10,而我的笔记本电脑操作系统是 Windows 11。 这会是问题所在吗?

PySide 在 PC 和笔记本电脑上的版本都是 PySide2。

thread-safety threadpool python-multithreading pyside2 qthread
1个回答
0
投票
接口类的方法不应该使用QThread或python线程来执行。

后台要做的操作应该继承QThread类来创建,并且数据传输应该通过信号槽连接来完成。

在Signal-Slot的数据传输过程中,分片发送数据比一次发送所有数据效果更好。这可能取决于处理器的功率。

import sys import time from PyQt5.QtCore import QThread, pyqtSignal from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel class WorkerThread(QThread): data = pyqtSignal(int) count = 0 def __init__(self): super().__init__() def run(self): while True: time.sleep(1) # Interface-related operations are done here self.data.emit(self.count) self.count += 1 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setGeometry(100, 100, 400, 200) self.label = QLabel(self) self.label.setGeometry(10, 10, 380, 180) # Create a worker thread self.worker_thread = WorkerThread() # Connect the signal self.worker_thread.data.connect(self.data_received) # Start the worker thread self.worker_thread.start() def data_received(self, data): self.label.setText(str(data)) if __name__ == "__main__": app = QApplication(sys.argv) win = MainWindow() win.show() sys.exit(app.exec_())
    
© www.soinside.com 2019 - 2024. All rights reserved.