将信号发射到线程
我正在使用PYQT5创建图形用户界面。 我想在执行一定过程时将信号发送到运行线程以更改参数。
我创建了一个简单的代码来演示我打算实现的目标。 下面的代码生成带有两个按钮的基本GUI。 按下第一个按钮时,创建并启动了一个线程,该线程每秒都会打印一个字符串。按下第二个按钮时,将修改显示的字符串并用另一个字符串替换。
我的问题是字符串永远不会更改,我不确定为什么。
import sys
from time import sleep
from PyQt5.QtCore import Qt, QMutex
from PyQt5.QtWidgets import (
QApplication,
QLabel,
QMainWindow,
QPushButton,
QVBoxLayout,
QWidget,
)
from PyQt5.QtCore import QObject, QThread, pyqtSignal
class Worker(QObject):
finished = pyqtSignal()
def __init__(self, parent=None):
super(Worker, self).__init__()
self.mutex = QMutex()
self.stringToDisplay = 'Holà'
def update(newStringToDisplay):
self.mutex.lock()
self.stringToDisplay = newStringToDisplay
self.mutex.unlock()
def run(self):
"""Long-running task."""
while 1:
sleep(1)
self.mutex.lock()
print(self.stringToDisplay)
self.mutex.unlock()
self.finished.emit()
class Window(QMainWindow):
updateSignal = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi()
def setupUi(self):
self.setWindowTitle("GUI")
self.resize(300, 150)
self.button2runThread = QPushButton('Click to start the thread', self)
self.button2runThread.clicked.connect(self.runThread)
self.button2updateParams = QPushButton('Click to update parameter in the running thread', self)
self.button2updateParams.clicked.connect(self.updateThread)
layout = QVBoxLayout()
layout.addWidget(self.button2runThread)
layout.addWidget(self.button2updateParams)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.centralWidget.setLayout(layout)
def updateThread(self):
self.updateSignal.emit('My new string')
def runThread(self):
self.thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.updateSignal.connect(self.worker.update)
self.thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
I'm creating a graphical user interface with PyQt5.
I want to send a signal to a running thread to change parameters while it is carrying out a certain process.
I created a simple code to demonstrate what I intend to achieve.
The code below generates a basic GUI with two push buttons.
When the first button is pressed, a thread is created and started, which prints a string every second. When the second button is pressed, the displayed string is modified and replaced with another string.
My issue is that the string is never changed, and I'm not sure why.
import sys
from time import sleep
from PyQt5.QtCore import Qt, QMutex
from PyQt5.QtWidgets import (
QApplication,
QLabel,
QMainWindow,
QPushButton,
QVBoxLayout,
QWidget,
)
from PyQt5.QtCore import QObject, QThread, pyqtSignal
class Worker(QObject):
finished = pyqtSignal()
def __init__(self, parent=None):
super(Worker, self).__init__()
self.mutex = QMutex()
self.stringToDisplay = 'Holà'
def update(newStringToDisplay):
self.mutex.lock()
self.stringToDisplay = newStringToDisplay
self.mutex.unlock()
def run(self):
"""Long-running task."""
while 1:
sleep(1)
self.mutex.lock()
print(self.stringToDisplay)
self.mutex.unlock()
self.finished.emit()
class Window(QMainWindow):
updateSignal = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi()
def setupUi(self):
self.setWindowTitle("GUI")
self.resize(300, 150)
self.button2runThread = QPushButton('Click to start the thread', self)
self.button2runThread.clicked.connect(self.runThread)
self.button2updateParams = QPushButton('Click to update parameter in the running thread', self)
self.button2updateParams.clicked.connect(self.updateThread)
layout = QVBoxLayout()
layout.addWidget(self.button2runThread)
layout.addWidget(self.button2updateParams)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.centralWidget.setLayout(layout)
def updateThread(self):
self.updateSignal.emit('My new string')
def runThread(self):
self.thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.updateSignal.connect(self.worker.update)
self.thread.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我能够指出这个问题。
在将工人移至线程之前,我将信号连接起来。
这是导致问题的代码的一部分:
以及完整的代码:
I was able to pinpoint the issue.
I connected the signal before moving the Worker to the thread.
Here's the part of code that was causing the issue:
and the complete code: