hustlei 2020-02-16
1、信号与槽函数基础‘‘‘信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行‘‘‘from PyQt5.QtWidgets import *import sysclass signal(QWidget): def __init__(self): super(signal,self).__init__() self.initUI() #编辑控件及其关联的信号 def initUI(self): self.resize(300,200) self.setWindowTitle("信号与槽函数基础") self.b = QPushButton("我的按钮",self) #利用第二个参数self直接可以显示在窗口,不用布局来进行添加控件 #信号与槽函数连接 self.b.clicked.connect(self.onclick) #编辑槽函数 def onclick(self): self.b.setText("信号已经发出") self.b.setStyleSheet("QPushButton(max-width:300px;min-width:300px)")if __name__=="__main__": app=QApplication(sys.argv) p=signal() p.show() sys.exit(app.exec_())
2、自定义信号‘‘‘对于一个大类的对象,可以自定义实现一种信号自定义信号的方式pyqtSignal()信号对象‘‘‘from PyQt5.QtWidgets import *from PyQt5.QtCore import *#定义一个信号类class MyTypesignal(QObject): #定义一个信号 senmsg=pyqtSignal(object) #编写一个信号相关触发的触发函数 def run(self): self.senmsg.emit("hello PyQT5") #通过run方法来发出message信息hello PyQt5#定义一个槽函数类class MySlot(QObject): def get(self,msg): print("信息:"+msg)if __name__ == "__main__": send=MyTypesignal() slot=MySlot()#将信号与槽函数连接 send.senmsg.connect(slot.get) send.run() #将信号与槽函数断开 send.senmsg.disconnect(slot.get) send.run()
3、发射多个参数的信号‘‘‘对于一个信号,可以设置通过一个触发函数,发出多个参数‘‘‘from PyQt5.QtWidgets import *from PyQt5.QtCore import *#定义一个信号类class MyTypesignal(QObject):#定义一个信号 senmsg=pyqtSignal(object) #指定发出一个参数,类型为object对象 #发射3个参数的信号 senmsg1=pyqtSignal(str,int,int) #编写一个信号相关触发的触发函数 def run(self):self.senmsg.emit("hello PyQT5") #通过run方法来发出message信息hello PyQt5 def run1(self): self.senmsg1.emit("hello PyQT5",3,4) # 通过run方法来发出message信息hello PyQt5#定义一个槽函数类class MySlot(QObject): def get(self,msg): print("信息:"+msg)def get1(self,msg,a,b): print(msg,a,b)if __name__ == "__main__": send=MyTypesignal() slot=MySlot() #将信号与槽函数连接 send.senmsg.connect(slot.get) send.senmsg1.connect(slot.get1) send.run() send.run1()#将信号与槽函数断开 send.senmsg.disconnect(slot.get) send.senmsg1.disconnect(slot.get1) send.run() send.run1()
4、为类添加多个信号‘‘‘为一个类添加多个信号(重载形式信号)对于一个重载多种形式的参数信号,触发和关联时都需要指定参数类型‘‘‘from PyQt5.QtCore import *#定义一个信号类class multisignal(QObject): #定义一个信号 signal1=pyqtSignal() #定义一个信号的传入参数为int类型 signal2=pyqtSignal(int) signal3=pyqtSignal(int,str) signal4=pyqtSignal(list) signal5=pyqtSignal(dict)#申明一个重载版本的信号,也就是槽函数的参数可以是int和str类型,也可以只有一个str类型的信号 signal6=pyqtSignal([int,str],[str]) def __init__(self): super(multisignal,self).__init__() self.signal1.connect(self.signalcall1) self.signal2.connect(self.signalcall2) self.signal3.connect(self.signalcall3) self.signal4.connect(self.signalcall4) self.signal5.connect(self.signalcall5)#关联槽函数时需要指定传入参数类型,对于多个发射参数形式的信号在了解时需要指定类型,不然默认第一种情况 self.signal6[int,str].connect(self.signalcall6) self.signal6[str].connect(self.signalcall6overload) self.signal1.emit() self.signal2.emit(10) self.signal3.emit(1,"hello") self.signal4.emit([1,2,3,4]) self.signal5.emit({"name":"燕江依","sex":"male"}) #发出参数时也需要指定信号的参数类型,默认关联到第一种类型上去,也就是int+str类型 self.signal6[int,str].emit(20,"test") self.signal6[str].emit("text") def signalcall1(self): print("signal1 emit") def signalcall2(self,val): print("signal2 emit,value:",val) def signalcall3(self,val,text): print("signal3 emit",val,text) def signalcall4(self, val): print("signal4 emit,value:", val) def signalcall5(self,val): print("signal6 emit",val)def signalcall6(self, val,text): print("signal6 emit,value:", val,text) def signalcall6overload(self, val): print("signal6 overload emit,value:", val)if __name__ == "__main__": mul=multisignal()
5、多线程更新UI数据(利用信号与槽函数在两个线程之间传递数据)from PyQt5.QtCore import QThread,pyqtSignal,QDateTimefrom PyQt5.QtWidgets import QApplication,QDialog,QLineEditimport timeimport sys#定义一个动态显示当前时间的线程类class back(QThread): update_date=pyqtSignal(str) def run(self): while True: date=QDateTime.currentDateTime() current=date.toString("yyyy-MM-dd hh:mm:ss") self.update_date.emit(str(current)) time.sleep(1)#定义一个主窗口class threadupdate(QDialog): def __init__(self): QDialog.__init__(self) self.setWindowTitle("多线程更新UI数据") self.resize(400,100) self.input=QLineEdit(self) self.input.resize(400,100) self.initUI() def initUI(self):self.backend=back() self.backend.update_date.connect(self.handledisplay) self.backend.start() #启动线程程序 def handledisplay(self,data): self.input.setText(data)if __name__=="__main__": app=QApplication(sys.argv) p=threadupdate() p.show() sys.exit(app.exec_())
6、信号与槽函数实现自动连接‘‘‘实现的方法详解如下:1、定义控件的名称,设置控件与信号连接的原则,以名称自动连接self.button.setObjectName("objectname")QtCore.QMetaObject.connectSlotsByName(self)2、槽函数格式为:@QtCore.pyqtSlot()def on_objectname_signalname(self):3、参数说明(1)objectname必须和关联控件名称一致(2)signalname必须和控件所需要关联的信号名称一致‘‘‘from PyQt5 import QtCorefrom PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QPushButtonimport sysclass autosignalslot(QWidget): def __init__(self): super(autosignalslot,self).__init__() self.ok=QPushButton("OK",self) #第一步设置关联信号控件按钮的名字 self.ok.setObjectName("okbutton") self.cancle = QPushButton("cancel",self) self.cancle.setObjectName("canclebutton")#第二步:设置信号与控件连接的原则 QtCore.QMetaObject.connectSlotsByName(self) layout = QHBoxLayout() layout.addWidget(self.ok) layout.addWidget(self.cancle) self.setLayout(layout) #使用手动定义关联关系来进行信号与槽函数的匹配 #self.ok.clicked.connect(self.on_okbutton)#第三步:定义槽函数:采用自动信号与槽函数之间的关联 @QtCore.pyqtSlot() def on_okbutton_clicked(self): print("点击了ok按钮") @QtCore.pyqtSlot() def on_canclebutton_clicked(self): print("点击了cancle按钮")if __name__=="__main__": app=QApplication(sys.argv) p=autosignalslot() p.show() sys.exit(app.exec_())
7、信号与槽函数连接与断开N对N连接‘‘‘1.一个信号关联多个槽函数2.一个槽函数可以被多个信号关联3.一个信号可以关联另外一个信号可以实现触发另外一个信号‘‘‘from PyQt5.QtCore import *class NNsignal(QObject): signal1=pyqtSignal() signal2=pyqtSignal(int) signal3=pyqtSignal(int) def __init__(self): super(NNsignal,self).__init__()#一个信号关联多个槽函数 self.signal1.connect(self.call1) self.signal1.connect(self.call2) self.signal2.connect(self.call3)#信号2触发信号3,信号关联信号,需要注意信号传入参数的一致性,不然触发不了 self.signal2.connect(self.signal3) #信号2和信号3关联,直接会触发信号3关联的槽函数#一个槽函数被多个信号关联 self.signal3.connect(self.call3) self.signal1.emit() #一个信号触发多个槽函数 self.signal2.emit(100) self.signal2.emit(2) def call1(self): print("call1 emit") def call2(self): print("call2 emit") def call3(self,int): print("call3 emit",int)if __name__ == "__main__": mul=NNsignal()
8、为窗口添加关闭窗口信号from PyQt5.QtCore import *from PyQt5.QtWidgets import *import sysclass winsignal(QWidget): buttonsignal=pyqtSignal() def __init__(self): super(winsignal,self).__init__() self.setWindowTitle("为窗口类添加窗口关闭信号") self.resize(300,100) b=QPushButton("关闭窗口",self)b.clicked.connect(self.b_click) self.buttonsignal.connect(self.b_close) def b_click(self): self.buttonsignal.emit() def b_close(self): self.close()if __name__=="__main__": app=QApplication(sys.argv) p=winsignal() p.show() sys.exit(app.exec_())
9、lambda表达式为槽函数传递参数‘‘‘python中的lambda表达式:没有名字的函数:即匿名函数‘‘‘#不带参数的函数定义fun=lambda :print("hello world")fun()#带参数函数的定义f=lambda x,y:x*y**2print(f(3,4))from PyQt5.QtWidgets import *import sysclass lambdaslot(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("使用lambda表达式为槽函数传递参数") self.b1=QPushButton("按钮1") self.b2=QPushButton("按钮2")#相当于click点击信号+lamda表达式便可以实现点击传入槽函数参数 self.b1.clicked.connect(lambda: self.onbutton(10, 20)) self.b2.clicked.connect(lambda: self.onbutton(10, -20)) self.b1.clicked.connect(lambda :QMessageBox.information(self,"结果","单击了button1")) lay=QHBoxLayout() lay.addWidget(self.b1) lay.addWidget(self.b2) m=QWidget() m.setLayout(lay) self.setCentralWidget(m)#槽函数需要参数,而button点击不能传入参数,可以使用lambda表达式传入参数 def onbutton(self,m,n): print("m+n=",m+n) QMessageBox.information(self,"结果",str(m+n))if __name__ == "__main__": app = QApplication(sys.argv) p =lambdaslot() p.show() sys.exit(app.exec_())
10、partial对象为槽函数传递参数‘‘‘python中的lpartial对象partial(f,参数1,参数2,...)‘‘‘from PyQt5.QtWidgets import *import sysfrom functools import partialclass partialslot(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("使用partial对象为槽函数传递参数") self.b1=QPushButton("按钮1") self.b2=QPushButton("按钮2")#相当于click点击信号+lamda表达式便可以实现点击传入槽函数参数 self.b1.clicked.connect(partial(self.onbutton,10,20)) self.b2.clicked.connect(partial(self.onbutton,20,-40)) lay=QHBoxLayout() lay.addWidget(self.b1) lay.addWidget(self.b2) m=QWidget() m.setLayout(lay) self.setCentralWidget(m) #槽函数需要参数,而button点击不能传入参数,可以使用partial对象传入参数 def onbutton(self,m,n): print("m+n=",m+n) QMessageBox.information(self,"结果",str(m+n))if __name__ == "__main__": app = QApplication(sys.argv) p =partialslot() p.show() sys.exit(app.exec_())
11、覆盖槽函数(键盘按键信号连接自定义槽函数)‘‘‘覆盖槽函数‘‘‘from PyQt5.QtWidgets import *from PyQt5.QtCore import Qtimport sys#按键信号与槽函数进行关联,自定义属性class overrideslot(QWidget): def __init__(self): super().__init__() self.setWindowTitle("覆盖槽函数")#系统里面的按键槽函数与信号连接,可以自定义槽函数里面的功能 def keyPressEvent(self, e): if e.key()==Qt.Key_Escape: self.close() elif e.key()==Qt.Key_Alt: self.setWindowTitle("按下了ALT键")if __name__ == "__main__": app = QApplication(sys.argv) p =overrideslot() p.show() sys.exit(app.exec_())