使用QObject从Python线程发出信号
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用QObject从Python线程发出信号,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2997字,纯文字阅读大概需要5分钟。
内容图文
![使用QObject从Python线程发出信号](/upload/InfoBanner/zyjiaocheng/824/134044feca2f48e782b34293c48b1ec6.jpg)
我想知道与QThread相比,从QObject中的常规python线程发出信号会产生什么后果.
请参阅以下课程:
class MyObject(QtCore.QObject):
def __init__(self):
super().__init__()
sig = pyqtSignal()
def start(self):
self._thread = Thread(target=self.run)
self._thread.start()
def run(self):
self.sig.emit()
# Do something
现在,假设在GUI线程中,我有:
def __init__(self):
self.obj = MyObject()
self.obj.sig.connect(self.slot)
self.obj.start()
def slot(self):
# Do something
在发出信号时确实执行了插槽.但是,我想知道插槽方法将在哪个线程中执行?如果我在MyObject中使用QThread而不是python线程会有什么不同吗?
我正在使用PyQt5和Python 3.
解决方法:
默认情况下,Qt automatically queues signals在跨线程发出时.为此,它将信号参数序列化,然后将事件发布到接收线程的事件队列,最终将执行任何连接的槽.因此,以这种方式发出的信号保证是线程安全的.
关于外部线程,Qt docs state以下内容:
Note: Qt’s threading classes are implemented with native threading
APIs; e.g., Win32 and pthreads. Therefore, they can be used with
threads of the same native API.
通常,如果文档声明Qt API is thread-safe,该保证适用于使用相同本机库创建的所有线程 – 而不仅仅是由Qt本身创建的线程.这意味着使用诸如postEvent()和invoke()之类的线程安全API将事件显式地发布到其他线程也是安全的.
因此,当发出跨线程信号时,使用threading.Thread和QThread之间没有真正的区别,只要Python和Qt都使用相同的底层本机线程库.这表明在PyQt应用程序中更喜欢使用QThread的一个可能原因是可移植性,因为没有混合不兼容的线程实现的危险.但是,鉴于Python和Qt都是故意设计为跨平台的,因此在实践中出现这个问题的可能性极小.
至于插槽将在哪个线程中执行的问题 – 对于Python和Qt,它将在主线程中.相反,run方法将在worker线程中执行.在Qt应用程序中执行多线程时,这是一个非常重要的考虑因素,因为在主线程之外执行gui操作是不安全的.使用信号允许您在工作线程和gui之间进行安全通信,因为连接到工作者发出的信号的插槽将在主线程中调用,允许您在必要时更新gui.
下面是一个简单的脚本,显示了调用每个方法的线程:
import sys, time, threading
from PyQt5 import QtCore, QtWidgets
def thread_info(msg):
print(msg, int(QtCore.QThread.currentThreadId()),
threading.current_thread().name)
class PyThreadObject(QtCore.QObject):
sig = QtCore.pyqtSignal()
def start(self):
self._thread = threading.Thread(target=self.run)
self._thread.start()
def run(self):
time.sleep(1)
thread_info('py:run')
self.sig.emit()
class QtThreadObject(QtCore.QThread):
sig = QtCore.pyqtSignal()
def run(self):
time.sleep(1)
thread_info('qt:run')
self.sig.emit()
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.pyobj = PyThreadObject()
self.pyobj.sig.connect(self.pyslot)
self.pyobj.start()
self.qtobj = QtThreadObject()
self.qtobj.sig.connect(self.qtslot)
self.qtobj.start()
def pyslot(self):
thread_info('py:slot')
def qtslot(self):
thread_info('qt:slot')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
thread_info('main')
sys.exit(app.exec_())
输出:
main 140300376593728 MainThread
py:run 140299947104000 Thread-1
py:slot 140300376593728 MainThread
qt:run 140299871450880 Dummy-2
qt:slot 140300376593728 MainThread
内容总结
以上是互联网集市为您收集整理的使用QObject从Python线程发出信号全部内容,希望文章能够帮你解决使用QObject从Python线程发出信号所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。