转自:http://blog.sina.com.cn/s/blog_613d5bb701016qzv.html

信号(singal)与槽(slot)用于对象相互通信,信号:当某个对象的某个事件发生时,触发一个信号,槽:响应指定信号的所做的反应,其实信号槽类似于.NET里面的委托、事件,比如Repeater控件类,当行数据绑定后,触发一个ItemDataBound事件,不管使用者使用会监听该事件并做额外处理,其控件类内部都会触发该事件,这种机制很多程度提高了类的封装性和完整性。

  PyQt的窗体控件类已经有很多的内置信号,开发者也可以添加自己的自定义信号,信号槽有如下特点:

    - 一个信号可以连接到许多插槽。
    - 一个信号也可以连接到另一个信号。
    - 信号参数可以是任何Python类型。
    - 一个插槽可以连接到许多信号。
    - 连接可能会直接(即同步)或排队(即异步)。
    - 连接可能会跨线程。
    - 信号可能会断开   (以上几条特点翻译于官方文档),接下来,我将以若干个实例,来体现以上几个特点。 内置信号槽的使用 from PyQt4.QtGui import *
from PyQt4.QtCore import * def sinTest():
btn.setText("按钮文本改变") app = QApplication([]) main = QWidget()
main.resize(200,100)
btn = QPushButton("按钮文本",main)
##按钮btn的内置信号连接名为sinTest的槽
btn.clicked.connect(sinTest)
main.show()
app.exec_() from PyQt4.QtGui import *
from PyQt4.QtCore import * def sinTest():
btn.setText("按钮文本改变") app = QApplication([]) main = QWidget()
main.resize(200,100)
btn = QPushButton("按钮文本",main)
##按钮btn的内置信号连接名为sinTest的槽
btn.clicked.connect(sinTest)
main.show()
app.exec_() from PyQt4.QtGui import *
from PyQt4.QtCore import * def sinTest():
btn.setText("按钮文本改变") app = QApplication([]) main = QWidget()
main.resize(200,100)
btn = QPushButton("按钮文本",main)
##按钮btn的内置信号连接名为sinTest的槽
btn.clicked.connect(sinTest)
main.show() app.exec_() 运行结果: 自定义信号槽的使用 from PyQt4.QtGui import *
from PyQt4.QtCore import * class SinClass(QObject): ##声明一个无参数的信号
sin1 = pyqtSignal() ##声明带一个int类型参数的信号
sin2 = pyqtSignal(int) ##声明带一个int和str类型参数的信号
sin3 = pyqtSignal(int,str) ##声明带一个列表类型参数的信号
sin4 = pyqtSignal(list) ##声明带一个字典类型参数的信号
sin5 = pyqtSignal(dict) ##声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号
sin6 = pyqtSignal([int,str], [str]) def __init__(self,parent=None):
super(SinClass,self).__init__(parent) ##信号连接到指定槽
self.sin1.connect(self.sin1Call)
self.sin2.connect(self.sin2Call)
self.sin3.connect(self.sin3Call)
self.sin4.connect(self.sin4Call)
self.sin5.connect(self.sin5Call)
self.sin6[int,str].connect(self.sin6Call)
self.sin6[str].connect(self.sin6OverLoad) ##信号发射
self.sin1.emit()
self.sin2.emit(1)
self.sin3.emit(1,"text")
self.sin4.emit([1,2,3,4])
self.sin5.emit({"name":"codeio","age":"25"})
self.sin6[int,str].emit(1,"text")
self.sin6[str].emit("text") def sin1Call(self):
print("sin1 emit") def sin2Call(self,val):
print("sin2 emit,value:",val) def sin3Call(self,val,text):
print("sin3 emit,value:",val,text) def sin4Call(self,val):
print("sin4 emit,value:",val) def sin5Call(self,val):
print("sin5 emit,value:",val) def sin6Call(self,val,text):
print("sin6 emit,value:",val,text) def sin6OverLoad(self,val):
print("sin6 overload emit,value:",val) sin = SinClass() 运行结果:
sin1 emit
sin2 emit,value: 1
sin3 emit,value: 1 text
sin4 emit,value: [1, 2, 3, 4]
sin5 emit,value: {'age': '25', 'name': 'codeio'}
sin6 emit,value: 1 text
sin6 overload emit,value: text 信号槽N对N连接、断开连接 from PyQt4.QtGui import *
from PyQt4.QtCore import * class SinClass(QObject): ##声明一个无参数的信号
sin1 = pyqtSignal() ##声明带一个int类型参数的信号
sin2 = pyqtSignal(int) def __init__(self,parent=None):
super(SinClass,self).__init__(parent) ##信号sin1连接到sin1Call和sin2Call这两个槽
self.sin1.connect(self.sin1Call)
self.sin1.connect(self.sin2Call) ##信号sin2连接到信号sin1
self.sin2.connect(self.sin1) ##信号发射
self.sin1.emit()
self.sin2.emit(1) ##断开sin1、sin2信号与各槽的连接
self.sin1.disconnect(self.sin1Call)
self.sin1.disconnect(self.sin2Call)
self.sin2.disconnect(self.sin1) ##信号sin1和sin2连接同一个槽sin1Call
self.sin1.connect(self.sin1Call)
self.sin2.connect(self.sin1Call) ##信号再次发射
self.sin1.emit()
self.sin2.emit(1) def sin1Call(self):
print("sin1 emit") def sin2Call(self):
print("sin2 emit") sin = SinClass() 运行结果:
sin1 emit
sin2 emit
sin1 emit
sin2 emit
sin1 emit
sin1 emit 多线程信号槽通信 from PyQt4.QtCore import *
from PyQt4.QtGui import * class Main(QWidget):
def __init__(self, parent = None):
super(Main,self).__init__(parent) ##创建一个线程实例并设置名称、变量、信号槽
self.thread = MyThread()
self.thread.setIdentity("thread1")
self.thread.sinOut.connect(self.outText)
self.thread.setVal(6) def outText(self,text):
print(text) class MyThread(QThread): sinOut = pyqtSignal(str) def __init__(self,parent=None):
super(MyThread,self).__init__(parent) self.identity = None def setIdentity(self,text):
self.identity = text def setVal(self,val):
self.times = int(val) ##执行线程的run方法
self.start() def run(self):
while self.times > 0 and self.identity:
##发射信号
self.sinOut.emit(self.identity+" "+str(self.times))
self.times -= 1 app = QApplication([]) main = Main()
main.show() app.exec_() 运行结果:
thread1 6
thread1 5
thread1 4
thread1 3
thread1 2
thread1 1   该篇主要介绍了信号槽多对多连接、连接断开、多线程如何使用信号槽进行通信,Qt除了窗体部件类,还提供了很多其他系统相关操作类,使用起来很方便,多线程使用了Qt自带的QThread类,这里只是做了个简单的测试,多线程还有许多要深入探究的,有几个心得:     - 对于单一信号连接多个槽的情况,发射信号后,槽的执行顺序就是信号槽连接的顺序     - GUI所在的线程是主线程,线程之间可以通过信号槽来通信,这个方法适用于重写PyQt部件类后对外开发接口     - 我使用的环境是:PyQt4.8.4,Qt4.7.2,Python3.2,这个版本的PyQt将使用新的信号槽风格     - 槽的参数个数可以小于等于信号的参数个数, 换句话说,信号并不关心谁使用了它,怎么使用它,槽可以选择性地使用信号的参数     - 用pyqtSignal来声明一个新信号,它的参数可能是Python的类型对象或者C++的类型     - 新的信号只能在QObject的子类中声明

个人注解:

 QMetaObject::invokeMethod()是Qt中的方法,在PyQt中应该也可行,但是没在PyQt试验过,。。。。。囧

转载:pyqt线程间通过 信号/槽 通信的更多相关文章

  1. [转]QT子线程与主线程的信号槽通信-亲测可用!

    近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号槽 ...

  2. 想在子线程里面触发的信号的槽函数在子线程执行,信号槽连接必须使用DirectConnection 方式(即使跨线程,也可以强迫DirectConnection,而不能是AutoConnection)

    Qt多线程的实现 1.继承QThread,重新run 2.继承Object,调用moveToThread方法 两种方法各有利弊:主要参考:http://blog.51cto.com/9291927/1 ...

  3. Pyqt 控件的信号槽事件定义方法

    转载来自:http://my.oschina.net/midnite/blog/39399 Qt采用信号槽来设定UI界面上元素动作的事件绑定.自Qt4.5开始,引入了一个新的信号槽与事件绑定的方法.界 ...

  4. Qt两个类通过信号槽通信

    qt需要通过信号槽来通信,connect的时候总是返回false,请教了公司的一个小哥,才解决了问题,虽然是个很白痴的问题. bool b = QObject::connect(m_pCollectO ...

  5. linux 线程间发送信号

    线程间通过 pthread_kill(thid,signo)给指定的thid线程发送signo信号. 创建线程与线程屏蔽字顺序 1. pthread_create();    pthread_sigm ...

  6. 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)

    使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...

  7. 说说Java线程间通信

    序言 正文 [一] Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在 ...

  8. 说说 Java 线程间通信

    序言 正文 一.Java线程间如何通信? 线程间通信的目标是使线程间能够互相发送信号,包括如下几种方式: 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值:线程A在一个 ...

  9. JUC---06线程间通信(二)

    二.线程间定制化调用通信 要使多线程之间按顺序调用,实现A->B->C按顺序输出,使用Lock锁实现,通过Lock锁创建三个Condition实例(三把钥匙),通过不同的条件,调用不同钥匙 ...

随机推荐

  1. unity c# script error CS0664: Literal of type double cannot be implicitly converted to type `float'. Add suffix `f' to create a literal of this type

    例如在unity c# script中定义 private float x=0.0; 则会报 error CS0664: Literal of type double cannot be implic ...

  2. How to install Mysql in the CentOS

    This article will walk through you the process of installing and updating latest MySQL 5.7.9 version ...

  3. FreeBSD搭建SVN服务器

    我最喜欢使用的OS就是FreeBSD,而且现在刚好有一台FreeBSD服务器,所以我想把我的SVN服务器迁移到FreeBSD上,再配合hudson和ant就可以自动编译了. 第一步:安装svn: 在安 ...

  4. ps减去图层混合模式

    ps减去图层混合模式 CMYK 1.1.青色作为基色,品红作为混合色(减去混合模式) 红反即青色(绿色+蓝色) - 绿反即品红色(红色+蓝色)= 绿色   公式简化: 绿色 + 蓝色 - 红色 - 蓝 ...

  5. [Jobdu] 题目1528:最长回文子串

    题目描述: 回文串就是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串.回文子串,顾名思义,即字符串中满足回文性质的子串.给出一个只由小写英文字符a,b,c...x,y, ...

  6. Android:EditText 属性

    Android开发EditText属性 EditText 官网链接 EditText继承关系:View-->TextView-->EditText EditText 部分属性: XML 设 ...

  7. mongo操作及相关资料

    mongo操作 find方法 db.collection_name.find(); 查询所有的结果: select * from users; db.users.find(); 指定返回那些列(键): ...

  8. 08、通过自定义依赖属性,用 StateTrigger 修改全局主题样式

    在 Win 10 的 UWP 中,需要在 xaml 中,通过使用 StateTrigger 修改全局的文本大小.Background.画刷等依赖属性等主题样式.下面只针对字体大小进行描述,其它依赖属性 ...

  9. sqlachemy中批量删除的问题

    db.session.query(Article).filter(Article.id.in_(items)).delete() 报错: sqlalchemy.exc.InvalidRequestEr ...

  10. VBA学习笔记(4)--数组和单元格互相转换

    说明(2017.3.23): 1. VBA的数组还是很难用的,其实就是非常难用! 2. 要先定义一个数组,可以是空的,也可以里面写个数字作为数组长度. 3. 如果是空数组,可以后面redim重新定义数 ...