python线程间通信的问题,回答有加分!300
如果用多进程进行测试会得不到具体的控件ID,而多线程的话会报一堆错误,如何在一个线程中发信号调用另一个线程的函数,并且GUI不会未响应。
:
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in ano
ther thread
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in ano
ther thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QObject::installEventFilter(): Cannot filter events for objects in a different t
hread.
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in ano
ther thread
QCoreApplication::sendPostedEvents: Cannot send posted events for objects in ano
ther thread
QObject::startTimer: QTimer can only be used with threads started with QThread
QObject::startTimer: timers cannot be started from another thread
QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread 展开
pyqt的线程之间的通信是通过信号to槽来实现的,首先你在线程类里面声明一个全局槽比如:
class imThread(QtCore.QThread):
imslot = QtCore.pyqtSignal()
这里是要重点注意,上面的是没有任何参数的一个信号,如果你需要参数的话,你可以在里面添加参数类型,例如:
imslot1 = QtCore.pyqtSignal(str) #这是一个带字符串参数的信号
imslot2 = QtCore.pyqtSignal(int) #这是一个带整型参数的信号
imslot3 = QtCore.pyqtSignal(bool) #这是一个带布尔参数的信号
当然了,如果你需要多个参数的话,同样地往里面加就是了,qt也没有要求参数必须是同类型的,所以可以这样:
imslot1 = QtCore.pyqtSignal(str, int) #这是一个带整型和字符串的参数信号
imslot2 = QtCore.pyqtSignal(int, str, str) #这是一个带整型和两个字符串的参数信号
imslot3 = QtCore.pyqtSignal(bool, str) #这是一个带布尔和字符串的参数信号
在线程的run方法里面来定义执行信号:
self.imslot.emit()
这里也是需要重点注意的是,上面这个接口是没有参数的,如果你是要参数的话,是需要这样写:
self.imslot1[str].emit('hello')
self.imslot2[int].emit(1)
self.imslot3[bool].emit(False)
多参数的是这样
self.imslot1[str, int].emit('hello', 1)
self.imslot2[int, str, str].emit(1, "hello", "world")
self.imslot3[bool, str].emit(False, 'hello')
以上就是在线程类里面完成信号定义了,接下来就是逻辑层成定义一个函数槽来连接线程类里面的信号,这个也很简单,比如我在主线程类里面定义一个方法:
def imSlot():
print 'ok'
以上这个是槽函数,接下来是实现信号槽的连接
imThread.imslot.connect('imSlot')
这个就是信号槽的连接方式,当然了,这个是没有参数的一个信号槽,那么带参数的怎么写呢?也很简单!首先定义一个槽函数:
def imSlot(para):
print para
这个是带参数的槽函数,下面是:
imThread.imslot[str].connect('imSlot')
以上就是线程之间的方法了,子线程在执行的通行经过执行信号的话,子线程可以安全地执行而不会出现GUI主线程卡死的情况了。
我用的是pyside,里面没有QtCore.pyqtSignal()这个方法,但是大意理解了,可是我再用QtCore.Signal()构造的时候一直提示AttributeError: 'PySide.QtCore.Signal' object has no attribute 'connect',没有这个方法。
对于pyside来说有什么实现多线程调用吗?
thread_1.testSignal.connect(x)
不管如何都会提示没有testSignal没有connect方法
首先你要先定义一个信号才行
self.testSignal= QtCore.pyqtSignal()
要在你的窗体中定义一个响应这个信号的槽
def handle_testSignal(self):
.....
然后连接这个信号和槽
self.testSignal.connect(self.handle_testSignal)
最后在你希望进行跨线程调用的地方发出这个信号
self.testSignal.emit()
没有你完整的原码,只能给个大至思路。
如果你闲signal-slot的方法麻烦可以用Queue,在工作线程中放入数据,在界面中加个定时器,定时取出数据并把数据在界面显示出来。