Duplicate instances of emit in pyqt5 when QThread is in use
- 2021-06-29 11:27:41
- OfStack
When using QThread in PyQt5, be aware that all QThread objects are instantiated in the init in the class (or outside all class functions), otherwise emit may repeat signals when multiple QThreads call each other.1 Generally, the correct writing is shown below. It is OK to build the frame according to this kind of framework.
# -*- coding: utf-8 -*-
import sys
import time
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class MainUi(QWidget):
def __init__(self):
super(MainUi, self).__init__()
self.resize(400, 200)
self.setWindowTitle('QThread Example ')
# Instantiate a multithreaded object
self.thread = Worker()
# Instantiate List Control and Button Control
self.listFile = QListWidget()
self.btnStart = QPushButton(' start ')
self.btn_over = QPushButton(' End ')
# Place controls in a raster layout
layout = QGridLayout(self)
layout.addWidget(self.listFile, 0, 0, 1, 2)
layout.addWidget(self.btnStart, 1, 0)
layout.addWidget(self.btn_over, 1, 1)
# Connection of signal to slot function
self.btnStart.clicked.connect(self.slotStart)
self.btn_over.clicked.connect(self.slot_btn_over)
# Establish slot connection for thread signal
self.thread.trigger.connect(self.slotAdd)
def slotAdd(self, msg):
print(msg)
if int(msg) % 2 == 0:
self.listFile.addItem(msg)
else:
pass
self.thread.exit()
def slotStart(self):
self.btnStart.setEnabled(False)
self.thread.start()
def slot_btn_over(self):
self.btnStart.setEnabled(True)
self.thread.terminate()
self.thread.num = 0
class Worker(QThread):
trigger = pyqtSignal(str)
num = 0
def __init__(self):
super(Worker, self).__init__()
def run(self):
while True:
print('num= ', self.num)
if self.num % 2 == 0:
self.trigger.emit(str(50))
elif self.num == 200:
self.num = 0
else:
pass
time.sleep(0.1)
self.num += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainUi()
w.show()
sys.exit(app.exec_())