我想圍繞如何正確使用線程和信號與PyQt5
和Python3
,但不知何故設法瞭解這一切如何工作。我在這裏找到了一個示例代碼,現在正試圖使它在PyQt5
中工作。PyQt信號和插槽:「新風格」散發?
這裏是GUI文件ui.py
:
from PyQt5 import QtCore, QtWidgets
class Ui_Win(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(416, 292)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
MainWindow.setCentralWidget(self.centralWidget)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_Win()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
這裏是主腳本test_slotting.py
:
from ui import Ui_Win
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtCore import pyqtSlot
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.pyqtSignal('itemSelectionChanged()'))
return
class MainUI(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self)
self.ui = Ui_Win()
self.ui.setupUi(self)
self.ui.List1 = QtWidgets.QListWidget(self)
self.ui.List2 = QtWidgets.QListWidget(self)
hbox = QtWidgets.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.itemSelectionChanged.connect(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 = QtWidgets.QApplication(sys.argv)
MainWindow = MainUI()
MainWindow.show()
sys.exit(app.exec_())
從最初的代碼示例中,我不得不改變 「舊式」
self.connect(genericThread, QtCore.SIGNAL("itemSelectionChanged()"), self.fill_List2)
以「新風格」
self.ui.List1.itemSelectionChanged.connect(self.start_heavy_processing_thread)
但是,現在我得到以下AttributeError: 'GenericThread' object has no attribute 'itemSelectionChanged'
。我想這條線從test_slotting.py
仍然是「舊式」:
self.emit(QtCore.pyqtSignal('itemSelectionChanged()'))
但是,什麼是它的新的風格的版本?任何幫助將不勝感激...
感謝您詳盡的解釋。爲此,使用'GenericThread'上的'itemSelectionChanged()'而不是'QListWidget'來犯愚蠢的錯誤。我仍然需要閱讀'QThread',thx的提示。 Thx也爲代碼示例,也將hv更詳細地檢查。我設法修補一下,讓我的例子運行。然而,仍然有一些我不是很瞭解(代碼中的評論,如果你喜歡,請隨時提供幫助:))。再次,thx爲您的幫助! – dliv
哦和P.S .:插圖真的非常有幫助! – dliv
很高興我能幫到你。正如我在我的答案中寫的 - 請看看我使用線程的git存儲庫。它應該足以讓你更好地掌握所有這些。 – rbaleksandar