zoukankan      html  css  js  c++  java
  • PyQt5信号与槽详解

    1、信号与槽函数基础
    '''
    信号与槽函数基础,信号是一个事件,发射信号之后槽函数就会执行
    '''
    from PyQt5.QtWidgets import *
    import sys

    class 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-300px;min-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,QDateTime
    from PyQt5.QtWidgets import QApplication,QDialog,QLineEdit
    import time
    import 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 QtCore
    from PyQt5.QtWidgets import QApplication,QWidget,QHBoxLayout,QPushButton
    import sys

    class 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 sys

    class 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**2
    print(f(3,4))

    from PyQt5.QtWidgets import *
    import sys
    class 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 sys
    from functools import partial

    class 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 Qt
    import 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_())






  • 相关阅读:
    容斥原理
    m元集A到n元集B的满射的个数
    二项式反演公式
    多项式定理
    组合数的基本性质
    Luogu P2408 不同子串个数
    Luogu P5410【模板】扩展 KMP
    Luogu P2336 [SCOI2012]喵星球上的点名
    Luogu P2852 [USACO06DEC]牛奶模式Milk Patterns
    Luogu P4248 [AHOI2013]差异
  • 原文地址:https://www.cnblogs.com/Yanjy-OnlyOne/p/12315797.html
Copyright © 2011-2022 走看看