使用pyqt5 开发一个线程带锁的启动,暂停,恢复,停止的案例
时间: 2023-05-27 13:01:58 浏览: 353
以下是一个使用PyQt5开发的线程带锁的启动、暂停、恢复和停止案例。这个案例使用了一个线程来模拟一个耗时的任务,使用一个锁来确保线程的安全。用户可以点击按钮来启动、暂停、恢复和停止任务。
```python
import sys
import threading
import time
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel
class WorkerThread(threading.Thread):
def __init__(self, lock):
super(WorkerThread, self).__init__()
self.lock = lock
self.stopped = False
self.paused = False
def run(self):
for i in range(0, 101):
with self.lock:
if self.paused:
while self.paused and not self.stopped:
time.sleep(0.1)
elif self.stopped:
break
else:
time.sleep(0.1)
self.progress_updated.emit(i)
self.finished.emit()
def pause(self):
self.paused = True
def resume(self):
self.paused = False
def stop(self):
self.stopped = True
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("Thread with Lock Example")
self.resize(300, 150)
self.lock = threading.Lock()
self.label = QLabel("0%")
self.button_start = QPushButton("Start")
self.button_pause = QPushButton("Pause")
self.button_resume = QPushButton("Resume")
self.button_stop = QPushButton("Stop")
self.button_pause.setEnabled(False)
self.button_resume.setEnabled(False)
self.button_stop.setEnabled(False)
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addLayout(self.create_button_layout())
self.setLayout(layout)
self.worker_thread = None
self.button_start.clicked.connect(self.start_task)
self.button_pause.clicked.connect(self.pause_task)
self.button_resume.clicked.connect(self.resume_task)
self.button_stop.clicked.connect(self.stop_task)
def create_button_layout(self):
layout = QHBoxLayout()
layout.addWidget(self.button_start)
layout.addWidget(self.button_pause)
layout.addWidget(self.button_resume)
layout.addWidget(self.button_stop)
return layout
def start_task(self):
self.button_start.setEnabled(False)
self.button_pause.setEnabled(True)
self.button_stop.setEnabled(True)
self.label.setText("0%")
self.worker_thread = WorkerThread(self.lock)
self.worker_thread.progress_updated.connect(self.update_progress)
self.worker_thread.finished.connect(self.task_finished)
self.worker_thread.start()
def pause_task(self):
self.button_pause.setEnabled(False)
self.button_resume.setEnabled(True)
self.worker_thread.pause()
def resume_task(self):
self.button_resume.setEnabled(False)
self.button_pause.setEnabled(True)
self.worker_thread.resume()
def stop_task(self):
self.button_pause.setEnabled(False)
self.button_resume.setEnabled(False)
self.button_stop.setEnabled(False)
self.worker_thread.stop()
def update_progress(self, value):
self.label.setText("{}%".format(value))
def task_finished(self):
self.button_start.setEnabled(True)
self.button_pause.setEnabled(False)
self.button_resume.setEnabled(False)
self.button_stop.setEnabled(False)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
```
在这个案例中,我们创建了一个`WorkerThread`类,它继承自`threading.Thread`。这个类中有一个锁`lock`,它确保线程的安全。在`run()`方法中,我们使用了`with self.lock`来锁住当前线程。如果线程处于暂停状态,我们将休眠线程直到它被恢复。如果线程处于停止状态,我们将中断循环。在`pause()`方法中,我们将暂停标志设置为`True`,在`resume()`方法中,我们将暂停标志设置为`False`。在`stop()`方法中,我们将停止标志设置为`True`。
在`MainWindow`类中,我们创建了一个带有四个按钮的用户界面,新建线程,并在“开始”按钮被单击时启动这个线程。当“暂停”、“恢复”和“停止”按钮被单击时,它们将调用`WorkerThread`类的相应方法。每当线程更新进度时,它会发射一个`progress_updated`信号,这个信号被连接到`update_progress()`方法中来更新UI上的标签。当线程完成时,它将发射一个`finished`信号,这个信号被连接到`task_finished()`方法中来重置用户界面的状态。
运行这个程序,我们可以看到一个用户界面,它包含了一个标签和四个按钮。单击“开始”按钮会启动一个线程,标签会显示任务的进度。在任务运行的任何时候,你都可以点击“暂停”、“恢复”和“停止”按钮。当任务完成时,你可以在单击“开始”按钮重新启动它。
阅读全文