PyQt线程完成并输出同一消息两次



我正在尝试创建一个带有进度条的播放/暂停/恢复/按钮。用户按下"开始",进度条初始化,并填充一个暂停/恢复按钮。进度完成后,将打印一条消息,暂停/继续按钮将隐藏,同时"开始"按钮将再次显示。但是,当我再次尝试运行"启动"时,它会再打印一次相同的完成消息。

如果我运行两次,它会打印出两条完成消息。运行三次,打印出三条完成消息等。

from PyQt5.QtWidgets import (
QWidget, QApplication, QProgressBar, QMainWindow,
QHBoxLayout, QPushButton
)

from PyQt5.QtCore import (
Qt, QObject, pyqtSignal, pyqtSlot, QRunnable, QThreadPool
)
import time

class WorkerSignals(QObject):
progress = pyqtSignal(int)
finished = pyqtSignal()
class JobRunner(QRunnable):

signals = WorkerSignals()

def __init__(self):
super().__init__()

self.is_paused = False
self.is_killed = False

@pyqtSlot()
def run(self):
for n in range(100):
self.signals.progress.emit(n + 1)
time.sleep(0.001)

while self.is_paused:
time.sleep(0)

if self.is_killed:
break
self.signals.finished.emit()

def finished(self):
print('Finished')

def pause(self):
self.is_paused = True

def resume(self):
self.is_paused = False

# def kill(self):

class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

# Some buttons
self.w = QWidget()
self.l = QHBoxLayout()
self.w.setLayout(self.l)

self.btn_start = QPushButton("Start")

self.l.addWidget(self.btn_start)

self.setCentralWidget(self.w)

# Create a statusbar.
self.status = self.statusBar()
self.progress = QProgressBar()
self.status.addPermanentWidget(self.progress)

# Thread runner
# self.threadpool = QThreadPool()

# # Create a runner
# self.runner = JobRunner()
# self.runner.signals.progress.connect(self.update_progress)
# self.threadpool.start(self.runner)
self.btn_start.pressed.connect(self.start_runner)
# btn_pause.pressed.connect(self.runner.pause)
# btn_resume.pressed.connect(self.runner.resume)

# self.startTestSignal.connect(self.update_progress)
self.show()

def update_progress(self, n):
self.progress.setValue(n)
def start_runner(self):
# Create ThreadPool
self.threadpool = QThreadPool()
self.threadpool.clear()
# Create a runner
self.runner = JobRunner()
self.runner.signals.progress.connect(self.update_progress)
self.threadpool.start(self.runner)
self.progress.setValue(0)

# Change Start Button to Pause
self.btn_start.hide()
# self.btn_start.setEnabled(False)
self.btn_pause = QPushButton("Pause")
self.btn_resume = QPushButton("Resume")
self.l.addWidget(self.btn_pause)
self.l.addWidget(self.btn_resume)
self.btn_pause.pressed.connect(self.runner.pause)
self.btn_resume.pressed.connect(self.runner.resume)
self.runner.signals.finished.connect(self.check)

def check(self):
print('Thread Done')
self.btn_start.show()
self.progress.setValue(0)
# self.runner.terminate()
self.btn_pause.hide()
self.btn_resume.hide()




app = QApplication([])
w = MainWindow()
app.exec_()

您正在创建一个WorkerSignals作为class属性,使其成为class的持久属性;所以当你这样做的时候:

self.runner.signals.finished.connect(self.check)

实际上,您正在将再次连接到signals.finished,当您发出信号时,每次连接信号时都会调用函数self.check

解决方案是将WorkerSignals创建为实例属性:

class JobRunner(QRunnable):
def __init__(self):
super().__init__()
self.signals = WorkerSignals()
self.is_paused = False
self.is_killed = False

最新更新