[英]Signals and Slots PyQt clarification
我注意到,有很多用户(包括我自己)对Qt中信号和插槽的概念不太了解。 我希望在以下方面得到一些澄清:
#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)
尽管可能非常错误,但是我尝试使用信号。 这是正确的方法吗? 我还收到一条错误消息,说“主窗口”对象没有属性“触发”,这是为什么?
谢谢。
收到该错误的原因正是错误消息所描述的原因-信号trigger
尚未在您的课程中的任何位置定义。 您需要先定义它,然后才能发出它。
信号和插槽用于在不同对象之间进行通信。 在您的示例中,您尝试从MainWindow
类中进行所有操作,并且与其他对象没有交互。 您还只需要调用一次connect()
。 在实例化要连接在一起的对象之后,通常可以在类构造函数中或从主函数中调用它。
看看http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html ,了解如何在PyQt中正确使用信号和插槽的一些示例。
对于线程,请使用QThread而不是threading.Thread,因为它可以更好地与Qt框架集成。 这篇文章展示了一些如何在PyQt中使用QThread的简单示例。 第二种方法(使用moveToThread()
)被认为是创建新线程的最正确方法。
您遇到的这类问题的基本思路是:
另请注意:
要添加到@ user3419537好的答案。 一个非常快速的线程示例:
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()
然后在您的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)
# 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))
您需要在应用程序关闭之前调用self.my_thread.quit()
才能停止线程并避免错误: QThread: Destroyed while thread is still running
self.my_thread.quit()
请阅读QMetaObject.invokeMethod的文档 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.