gpt4 book ai didi

python - 为什么需要 processEvents() 才能让 QThread 工作?

转载 作者:行者123 更新时间:2023-11-30 22:20:37 29 4
gpt4 key购买 nike

下面是我的代码,用于列出目录的所有子目录。我用它来理解 PySide 中的 QThread 以及信号和槽。问题是,当我没有在 Main 类的 scan() 方法中使用 Qtcore.QApplication.processEvents() 时,代码不起作用。事件循环还没有运行吗?

import sys
import os
import time
from PySide import QtGui, QtCore

class Scanner(QtCore.QObject):
folderFound = QtCore.Signal(str)
done = QtCore.Signal()
def __init__(self, path):
super(Scanner, self).__init__()
self.path = path

@QtCore.Slot()
def scan(self):
for folder in os.listdir(self.path):
time.sleep(1)
self.folderFound.emit(folder)

class Main(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.resize(420,130)
self.setWindowTitle('Threads')
self.lyt = QtGui.QVBoxLayout()
self.setLayout(self.lyt)

self.topLyt = QtGui.QHBoxLayout()
self.lyt.addLayout(self.topLyt)
self.scanBtn = QtGui.QPushButton('Scan')
self.scanBtn.clicked.connect(self.scan)
self.clearBtn = QtGui.QPushButton('Clear')
self.topLyt.addWidget(self.scanBtn)
self.topLyt.addWidget(self.clearBtn)

self.folders = list()

self.show()

def scan(self):
self.th = QtCore.QThread()
scanner = Scanner(r"D:\\")
scanner.moveToThread(self.th)

scanner.folderFound.connect(self.addFolder)
scanner.done.connect(scanner.deleteLater)
scanner.done.connect(self.quit)

self.th.started.connect(scanner.scan)
self.th.start()

QtCore.QApplication.processEvents()

@QtCore.Slot()
def addFolder(self, folder):
lbl = QtGui.QLabel(folder)
self.folders.append(lbl)

self.lyt.addWidget(lbl)

@QtCore.Slot()
def quit(self):
self.th.quit()
self.th.wait()

if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Main()
app.exec_()

最佳答案

您的示例能够正常工作纯属侥幸。

当您尝试调用QtCore.QApplication.processEvents()时,将会引发NameError,因为QApplication类实际上位于QtGui 模块,而不是 QtCore 模块。但是,引发异常会产生副作用,导致您的 scanner 对象无法被垃圾收集,因此线程看起来会正常运行。

修复代码的正确方法是保留对 scanner 对象的引用,并删除不需要的 processEvents 行:

def scan(self):
self.th = QtCore.QThread()
# keep a reference to the scanner
self.scanner = Scanner(r"D:\\")
self.scanner.moveToThread(self.th)

self.scanner.folderFound.connect(self.addFolder)
self.scanner.done.connect(self.scanner.deleteLater)
self.scanner.done.connect(self.quit)

self.th.started.connect(self.scanner.scan)
self.th.start()

其余代码没问题,该示例现在将按预期工作。

关于python - 为什么需要 processEvents() 才能让 QThread 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48801992/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com