我正在尝试编写一个运行时间很长的pyqt5应用程序,但不是CPU密集型进程。我希望能够在不挂起UI的情况下运行它,所以我正在尝试使用线程,但是因为我似乎不能只运行一个线程并在它通过其代码后停止它以便它可以再次运行,我已经尝试设置线程以等待变量在运行之前更改。
我知道这不是在pyqt应用程序中运行长进程的正确模式。
import time
import threading
from PyQt5 import QtWidgets, uic
class MyApp(QtWidgets.QMainWindow):
_run_thread = False
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = uic.loadUi('myapp.ui', self)
self.ui.start_thread_button.clicked.connect(self._run_thread_function)
self._thread = threading.Thread(target=self._run_thread_callback)
self._thread.daemon = True
self._thread.start()
self.ui.show()
def _run_thread_callback(self):
while True:
if self._run_thread:
print("running thread code...")
time.sleep(10)
print("thread code finished")
self._run_thread = False
def _run_thread_function(self):
print("starting thread...")
self._run_thread = True
def main():
app = QtWidgets.QApplication(sys.argv)
MyApp()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
答案 0 :(得分:1)
下面是一个简单的演示,展示了如何启动和停止工作线程,以及使用gui线程安全地进行comminucate。
import sys
from PyQt5 import QtCore, QtWidgets
class Worker(QtCore.QThread):
dataSent = QtCore.pyqtSignal(dict)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
self._stopped = True
self._mutex = QtCore.QMutex()
def stop(self):
self._mutex.lock()
self._stopped = True
self._mutex.unlock()
def run(self):
self._stopped = False
for count in range(10):
if self._stopped:
break
self.sleep(1)
data = {
'message':'running %d [%d]' % (
count, QtCore.QThread.currentThreadId()),
'time': QtCore.QTime.currentTime(),
'items': [1, 2, 3],
}
self.dataSent.emit(data)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.edit = QtWidgets.QPlainTextEdit()
self.edit.setReadOnly(True)
self.button = QtWidgets.QPushButton('Start')
self.button.clicked.connect(self.handleButton)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.button)
self._worker = Worker()
self._worker.started.connect(self.handleThreadStarted)
self._worker.finished.connect(self.handleThreadFinished)
self._worker.dataSent.connect(self.handleDataSent)
def handleThreadStarted(self):
self.edit.clear()
self.button.setText('Stop')
self.edit.appendPlainText('started')
def handleThreadFinished(self):
self.button.setText('Start')
self.edit.appendPlainText('stopped')
def handleDataSent(self, data):
self.edit.appendPlainText('message [%d]' %
QtCore.QThread.currentThreadId())
self.edit.appendPlainText(data['message'])
self.edit.appendPlainText(data['time'].toString())
self.edit.appendPlainText(repr(data['items']))
def handleButton(self):
if self._worker.isRunning():
self._worker.stop()
else:
self._worker.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 100, 400, 400)
window.show()
sys.exit(app.exec_())