我已经使用 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。
后台要做的操作应该继承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_())