[英]PyQt QThread MultiThreading does not work
我有2個QListWidget
列表,當從List1中選擇某些項時,正在填充List2
問題是,在填充List2之前,我必須執行很多任務,這會使UI凍結約5秒鍾,這太煩人了,我想讓它用QThread填充List2,但由於在初始化整個類之前我無法使用它一個煩人的錯誤
from ui import Ui_Win
from PyQt4 import QtGui, QtCore
class GenericThread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self, parent)
def __del__(self):
self.quit()
self.wait()
def run(self):
self.emit( QtCore.SIGNAL('itemSelectionChanged()'))
return
class MainUI(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_Win()
self.ui.setupUi(self)
...
genericThread = GenericThread(self)
self.connect(genericThread, QtCore.SIGNAL("itemSelectionChanged()"), self.fill_List2 )
genericThread.start()
def fill_List2(self):
self.ui.List2.clear()
list1SelectedItem = str(self.ui.List1.currentItem().text()) # ERROR HERE
# AttributeError: 'NoneType' object has no attribute 'text'
這是因為self.ui.List1.currentItem().text()
為None
為什么在觸發itemSelectionChanged
信號之前調用此功能?
from ui import Ui_Win ## ui.py is a file that has been generated from Qt Designer and it contains main GUI objects like QListWidget
from PyQt4 import QtGui, QtCore
class GenericThread(QtCore.QThread):
def __init__(self, parent=None, listIndex=0):
QtCore.QThread.__init__(self, parent)
self.listIndex = listIndex
def __del__(self):
self.quit()
self.wait()
def run(self):
if self.listIndex == 2:
for addStr in Something:
#Some long stuff
self.emit( QtCore.SIGNAL('fillListWithItems(QString, int'), addStr, self.listIndex)
class MainUI(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_Win()
self.ui.setupUi(self)
...
self.ui.List1.list1SelectedItem.connect(self.fill_List2)
@QtCore.pyqtSlot(QString, int)
def self.fillListWithItems(addStr, lstIdx):
if lstIdx==2:
self.ui.List2.addItem(addStr)
def fill_List2(self):
self.ui.List2.clear()
list1SelectedItem = str(self.ui.List1.currentItem().text())
genericThread = GenericThread(self, listIndex=2)
self.connect(genericThread, QtCore.SIGNAL("fillListWithItems(QString, int)"), self.fillListWithItems )
genericThread.start()
謝謝@ekhumoro
您的問題是,簡單地啟動線程會觸發itemSelectionChanged()
信號(因為它在run
函數中),該信號已連接到fill_List2()
函數。 您需要將List1
上的itemSelectionChanged
事件連接到一個SLOT
,該事件將觸發線程進行大量計算並更新List2
。
我必須對ui
是什么以及List1
和List2
是什么以及它們的設置方式做出一些假設,但這是一個有效的示例。 我已經用2秒的簡單延遲替換了GenericThread
的繁重計算。
如果我誤解了/做出了錯誤的假設,請更新問題並發表評論
from ui import Ui_Win
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSlot
from PyQt4.QtGui import *
import time
class GenericThread(QtCore.QThread):
def __init__(self, parent=None):
QtCore.QThread.__init__(self, parent)
def __del__(self):
self.quit()
self.wait()
def run(self):
#Do all your heavy processing here
#I'll just wait for 2 seconds
time.sleep(2)
self.emit( QtCore.SIGNAL('itemSelectionChanged()'))
return
class MainUI(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self)
self.ui = Ui_Win()
self.ui.setupUi(self)
self.ui.List1 = QListWidget(self)
self.ui.List2 = QListWidget(self)
hbox = QtGui.QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(self.ui.List1)
hbox.addWidget(self.ui.List2)
self.ui.centralWidget.setLayout(hbox)
self.ui.List1.addItems(['alpha','beta','gamma','delta','epsilon'])
self.ui.List2.addItems(['Item1','Item2'])
self.ui.List1.itemSelectionChanged.connect(self.start_heavy_processing_thread)
@pyqtSlot()
def start_heavy_processing_thread(self):
genericThread = GenericThread(self)
self.connect(genericThread, QtCore.SIGNAL("itemSelectionChanged()"), self.fill_List2 )
genericThread.start()
def fill_List2(self):
self.ui.List2.clear()
list1SelectedItem = str(self.ui.List1.currentItem().text())
self.ui.List2.addItem(list1SelectedItem)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = MainUI()
MainWindow.show()
sys.exit(app.exec_())
from PyQt4 import QtCore, QtGui
class Ui_Win(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(416, 292)
self.centralWidget = QtGui.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
MainWindow.setCentralWidget(self.centralWidget)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_Win()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.