信号和插槽 PyQt 澄清 [英] Signals and Slots PyQt clarification
问题描述
我注意到有很多用户,包括我自己,不太了解 Qt 中信号和槽的概念.我希望得到一些关于以下方面的澄清:
#我有一个函数,它在构建 GUI 后立即运行,它从以下位置获取信息#a list 并将其放入一个字符串中,然后将其上传到 texbox.在这个底部#loop,我希望它通过信号和槽调用父线程中的函数,如#其他用户推荐.
class MainWindow(QtGui.QMainWindow):#构建GUI所需的所有代码thread_mythread = threading.Thread(target = self.updateText, args = ())thread_mythread.start()def clearText(self):self.TextEdit.clear()def updateText(self):self.trigger.connect(self.clearText)为真:self.trigger.emit()NewString = list.pop(0)#我想我可能必须使用 append,因为 setText() 在父线程之外是不安全的self.TextEdit.append(NewString)
虽然可能非常不正确,但我尝试使用信号.这是正确的方法吗?我还收到一条错误消息,指出主窗口对象没有触发器"属性,这是为什么?
谢谢.
添加到@user3419537 好答案.一个非常快速的线程示例:
from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal, QThread, \Q_ARG、Qt、QMetaObject类 MyWorker(QObject):# 定义信号清除 = pyqtSignal()update_text_signal = pyqtSignal(str) # 传回一个字符串完成 = pyqtSignal()def __init__(self, parent=None):super(MyWorker, self).__init__(parent)# 添加函数等@pyqtSlot(列表)def update_text(self, string_list):#密集操作self.clear.emit() # 移到 while 之外而(真):#这是无限循环所以线程永远运行new_string = self.string_list.pop(0)self.update_text_signal.emit(new_string) # 修复了这一行#完成的self.finished.emit()
然后在您的 MainWindow 类中
self.my_thread = QThread()self.handler = MyWorker()self.handler.moveToThread(self.my_thread)self.handler.clear.connect(self.clearText)self.handler.update_text_signal.connect(self.update_line_edit)self.handler.finished.connect(self.my_thread.quit)# 开始线程self.my_thread.start()@pyqtSlot(str)def update_line_edit(self, text):self.TextEdit.append(text)QMetaObject.invokeMethod(self.handler, 'update_text',Qt.QueuedConnection,Q_ARG(列表,字符串列表))
您需要在应用程序关闭之前调用 self.my_thread.quit()
以停止线程并避免错误:QThread: Destroyed while thread is still running
请阅读 QMetaObject.invokeMethod 的文档.>
I have noticed that there are a lot of users, myself included, who don't quite grasp the concept of signals and slots in Qt. I was hoping to get some clarification on the following:
#I have a function that runs as soon as the GUI is built, this takes the information from
#a list and puts it into a string which is then uploaded to a texbox. At the bottom of this
#loop, I want it to call a function in the parent thread via signals and slots, as
#recommended by other users.
class MainWindow(QtGui.QMainWindow):
#all the code needed to build the GUI
thread_mythread = threading.Thread(target = self.updateText, args = ())
thread_mythread.start()
def clearText(self):
self.TextEdit.clear()
def updateText(self):
self.trigger.connect(self.clearText)
while True:
self.trigger.emit()
NewString = list.pop(0)
#I think I may have to use append, as setText() is not safe outside of the parent thread
self.TextEdit.append(NewString)
Although probably terribly incorrect, I attempt to use signals. Is this the proper way to do it? I also get an error that says that the Main Window object has no attribute "trigger",why is this?
thank you.
To add to @user3419537 good answer. A very quick threading example:
from PyQt4.QtCore import QObject, pyqtSlot, pyqtSignal, QThread, \
Q_ARG, Qt, QMetaObject
class MyWorker(QObject):
# define signal
clear = pyqtSignal()
update_text_signal = pyqtSignal(str) # passes a string back
finished = pyqtSignal()
def __init__(self, parent=None):
super(MyWorker, self).__init__(parent)
# Add functions etc.
@pyqtSlot(list)
def update_text(self, string_list):
#Intensive operation
self.clear.emit() # moved outside of while
while(True):
#This is infinite loop so thread runs forever
new_string = self.string_list.pop(0)
self.update_text_signal.emit(new_string) # Fixed this line
#Finished
self.finished.emit()
Then in your MainWindow class
self.my_thread = QThread()
self.handler = MyWorker()
self.handler.moveToThread(self.my_thread)
self.handler.clear.connect(self.clearText)
self.handler.update_text_signal.connect(self.update_line_edit)
self.handler.finished.connect(self.my_thread.quit)
# Start Thread
self.my_thread.start()
@pyqtSlot(str)
def update_line_edit(self, text):
self.TextEdit.append(text)
QMetaObject.invokeMethod(self.handler, 'update_text',
Qt.QueuedConnection,
Q_ARG(list, string_list))
You will need to call self.my_thread.quit()
before your application closes to stop the thread and avoid the error: QThread: Destroyed while thread is still running
Please read docs for QMetaObject.invokeMethod.
这篇关于信号和插槽 PyQt 澄清的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!