- import time
-
- from PyQt5.Qt import *
-
-
- class WorkThread(QThread):
- finished=pyqtSignal()
- def __init__(self):
- super(WorkThread, self).__init__()
- self.is_running = None
-
- def run(self):
- print('running')
- self.is_running = True
- while self.is_running:
- print('working....')
- time.sleep(1)
- self.finished.emit()
-
- def stop(self):
- self.is_running = False
-
-
-
- class MainWindow(QMainWindow):
- def __init__(self):
- super(MainWindow, self).__init__()
- self.resize(600,500)
- self.work = WorkThread()
- self.work.setParent(self)
- self.work.destroyed.connect(lambda :print('thread is destoryed'))
-
- self.btn = QPushButton("start")
- self.btn2 = QPushButton("stop")
-
- layout = QVBoxLayout()
- layout.addWidget(self.btn)
- layout.addWidget(self.btn2)
-
- central_widget = QWidget()
- central_widget.setLayout(layout)
-
- self.setCentralWidget(central_widget)
-
- #slots
- self.btn.clicked.connect(self.start_thread)
- self.btn2.clicked.connect(self.stop_thread)
-
- def start_thread(self):
- self.work.start()
-
- def stop_thread(self):
- self.work.stop()
-
- def closeEvent(self, event) -> None:
- self.work.stop()
-
-
在运行时关闭窗口时会出错的原因是,当关闭窗口时,工作线程仍然在运行,并且在调用`self.work.stop()`时,工作线程已经被销毁,但是在`stop()`方法中仍然尝试设置`self.is_running`为False,这会导致AttributeError。
为了解决这个问题,你可以在关闭窗口时先停止工作线程,然后再关闭窗口。你可以在`closeEvent`方法中添加一个判断,如果工作线程正在运行,则先停止工作线程,然后再关闭窗口。代码如下:
```python
def closeEvent(self, event):
if self.work.isRunning():
self.work.stop()
self.work.wait() # 等待工作线程结束
event.accept()
```
这样,当关闭窗口时,会先停止工作线程并等待其结束,然后再关闭窗口,避免了出错的情况。
正确代码如下:
- import time
-
- from PyQt5.Qt import *
-
-
- class WorkThread(QThread):
-
- def __init__(self):
- super(WorkThread, self).__init__()
- self.is_running = None
-
- def run(self):
- print('running')
- self.is_running = True
- while self.is_running:
- print('working....')
- time.sleep(1)
-
-
- def stop(self):
- self.is_running = False
-
-
-
- class MainWindow(QMainWindow):
- def __init__(self):
- super(MainWindow, self).__init__()
- self.resize(600,500)
- self.work = WorkThread()
- self.work.setParent(self)
- self.work.destroyed.connect(lambda :print('thread is destoryed'))
-
- self.btn = QPushButton("start")
- self.btn2 = QPushButton("stop")
-
- layout = QVBoxLayout()
- layout.addWidget(self.btn)
- layout.addWidget(self.btn2)
-
- central_widget = QWidget()
- central_widget.setLayout(layout)
-
- self.setCentralWidget(central_widget)
-
- #slots
- self.btn.clicked.connect(self.start_thread)
- self.btn2.clicked.connect(self.stop_thread)
-
- def start_thread(self):
- self.work.start()
-
- def stop_thread(self):
- self.work.stop()
-
- def closeEvent(self, event) -> None:
- if self.work.isRunning():
- self.work.stop()
- self.work.wait()
- event.accept()
- import time
-
- from PyQt5.Qt import *
- import time
-
- qum_1 = QMutex()
- class Thread_1(QThread):
-
- def __init__(self):
- super(Thread_1, self).__init__()
-
- def run(self):
- qum_1.lock()
- values=[1,2,3,4,5]
- for i in values:
- print(i)
- time.sleep(0.5)
- qum_1.unlock()
-
-
- class Thread_2(QThread):
- _signal = pyqtSignal()
-
- def __init__(self):
- super(Thread_2, self).__init__()
-
- def run(self):
- values = ["a","b","c","d","e"]
- for i in values:
- print(i)
- time.sleep(1)
- self._signal.emit()
-
-
-
-
-
-
- class Window(QWidget):
- def __init__(self):
- super().__init__()
- self.setWindowTitle("的学习")
- self.resize(500,500)
- self.setup_ui()
-
- self.t=Thread_1()
- self.t2=Thread_2()
- self.t2._signal.connect(lambda :self.btn2.setEnabled(True))
-
-
- def setup_ui(self):
-
- self.btn = QPushButton('btn1',self)
- self.btn.move(10,20)
- self.btn.clicked.connect(self.btn_click)
-
- self.btn2 = QPushButton('btn2',self)
- self.btn.move(10,80)
- self.btn2.clicked.connect(self.btn2_click)
-
-
- def btn_click(self):
- self.t.start()
-
- def btn2_click(self):
- self.btn2.setEnabled(False)
- self.t2.start()
-
-
-
-
-
- if __name__ == '__main__':
- import sys
- app=QApplication(sys.argv)
-
- win=Window()
- win.show()
- sys.exit(app.exec_())
- import threading
- import time
-
-
- class Task(threading.Thread):
- def __init__(self):
- super(Task, self).__init__()
-
- self._stop_event = threading.Event()
-
- def run(self):
- while not self._stop_event.is_set():
- print('hello')
-
- def stop(self):
- self._stop_event.set()
-
-
- t=Task()
- t.start()
- time.sleep(5)
- t.stop()