PyQt5入门(二十一)信号与槽(中)

目录

一.为窗口添加信号

二.多线程更新UI数据

三.信号与槽自动连接

四.用Lambda表达式为槽函数传递参数

五.用partial对象为槽函数传递参数

六.override(覆盖)槽函数


一.为窗口添加信号

本质就是为一个类添加信号,只不过这个类是窗口类。

代码:

import sys,math
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class WinSignal(QWidget):
    #定义一个信号
    btn_clicked_signal=pyqtSignal()

    def __init__(self):
        super(WinSignal, self).__init__()
        self.setWindowTitle('为窗口添加信号')
        self.resize(300,100)

        btn=QPushButton('关闭窗口',self)
        btn.clicked.connect(self.btn_clicked)
        self.btn_clicked_signal.connect(self.btn_close)

    #起触发函数作用的槽函数
    def btn_clicked(self):
        self.btn_clicked_signal.emit()
    #关闭窗口作用的槽函数
    def btn_close(self):
        self.close()



if __name__=='__main__':
    app=QApplication(sys.argv)
    main=WinSignal()
    main.show()
    sys.exit(app.exec_())

运行结果:

扫描二维码关注公众号,回复: 13025684 查看本文章

二.多线程更新UI数据

在两个线程中传递数据。

代码:

import sys,math
import time
from PyQt5.QtWidgets import QApplication,QDialog,QLineEdit
from PyQt5.QtCore import QThread,pyqtSignal,QDateTime


class BackendThread(QThread):
    #更新日期的信号
    update_date=pyqtSignal(str)
    def run(self):
        while True:
            date=QDateTime.currentDateTime()
            currentTime=date.toString('yyyy-MM-dd hh:mm:ss')
            #信号参数是当前时间
            self.update_date.emit(str(currentTime))
            time.sleep(1)#隔1s就发送一次信号


class ThreadUpdateUI(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=BackendThread()
        self.backend.update_date.connect(self.handleDisplay)
        self.backend.start()#开启线程,自动调用run

    # 槽函数是主线程
    def handleDisplay(self,data): #data是当前时间
        self.input.setText(data)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=ThreadUpdateUI()
    main.show()
    sys.exit(app.exec_())

运行结果:

三.信号与槽自动连接

代码:

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.resize(300,100)

        self.okBtn=QPushButton('ok',self)
        self.okBtn1=QPushButton('cancel',self)
        #设置自动连接
        self.okBtn.setObjectName('okBtn')
        self.okBtn1.setObjectName('cancelBtn')
        QtCore.QMetaObject.connectSlotsByName(self)


        layout=QHBoxLayout()
        layout.addWidget(self.okBtn)
        layout.addWidget(self.okBtn1)
        self.setLayout(layout)
        #传统连接信号与槽
        #self.okBtn.clicked.connect(self.on_okBtn_clicked)

    #命名规则:on_发送者对象(objectname)名称_发射信号名称(self,参数)
    @QtCore.pyqtSlot() #标注为槽函数,以供自动连接使用
    def on_okBtn_clicked(self):
        print('点击了ok按钮')

    @QtCore.pyqtSlot()
    def on_cancelBtn_clicked(self):
        print('点击了cancel按钮')


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=AutoSignalSlot()
    main.show()
    sys.exit(app.exec_())

运行结果:

 

四.用Lambda表达式为槽函数传递参数

Lambda表达式:匿名函数,也就是没有名字的函数。

将Lambda赋给一个变量,这个变量就成为了一个函数引用。或者将Lambda表达式作为一个参数传入函数。

代码:

#Lambda表达式示例
fun=lambda :print('hello world')
fun()

fun=lambda x,y:print(x,y)
fun('a','b')


from PyQt5.QtWidgets import *
import sys

class LambdaSlotArg(QMainWindow):
    def __init__(self):
        super(LambdaSlotArg, self).__init__()
        self.setWindowTitle('用Lambda表达式为槽函数传递参数')

        btn1=QPushButton('按钮1')
        btn2 = QPushButton('按钮2')

        ok=100
        btn1.clicked.connect(lambda :self.onButtonClick(10,ok))
        btn2.clicked.connect(lambda: self.onButtonClick(ok, -20))
        btn1.clicked.connect(lambda :QMessageBox.information(self,'结果','单击了btn1'))

        layout=QHBoxLayout()
        layout.addWidget(btn1)
        layout.addWidget(btn2)

        mainFrame=QWidget()
        mainFrame.setLayout(layout)
        self.setCentralWidget(mainFrame)

    def onButtonClick(self,m,n):
        print('m+n=',m+n)
        QMessageBox.information(self,'结果',str(m+n))


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=LambdaSlotArg()
    main.show()
    sys.exit(app.exec_())

运行结果:

        

五.用partial对象为槽函数传递参数

代码:

from PyQt5.QtWidgets import *
from functools import partial
import sys

class PartialSlotArg(QMainWindow):
    def __init__(self):
        super(PartialSlotArg, self).__init__()
        self.setWindowTitle('用partial对象为槽函数传递参数')

        btn1=QPushButton('按钮1')
        btn2 = QPushButton('按钮2')

        x=20
        y=-123
        btn1.clicked.connect(partial(self.onButtonClick,10,20))
        btn2.clicked.connect(partial(self.onButtonClick,x,y))

        layout=QHBoxLayout()
        layout.addWidget(btn1)
        layout.addWidget(btn2)

        mainFrame=QWidget()
        mainFrame.setLayout(layout)
        self.setCentralWidget(mainFrame)

    def onButtonClick(self,m,n):
        print('m+n=',m+n)
        QMessageBox.information(self,'结果',str(m+n))


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=PartialSlotArg()
    main.show()
    sys.exit(app.exec_())

运行结果:

效果和前面一样,只不过是用partial类来传递槽函数。

六.override(覆盖)槽函数

系统已经定义了很多槽函数,我们能可以覆盖重写这些槽函数。

代码:

注意一点:函数是小驼峰命名法!!!!!!!!!!!

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys

class OverrideSlot(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('override(覆盖)槽函数')
    #键盘按下的槽函数,不需要连接,系统已经给连接了
    def keyPressEvent(self,e):
        #如果按下Esc键,则关闭窗口
        if e.key()==Qt.Key_Escape:
            self.close()
        #如果按下Alt键,修改窗口标题为 按下Alt键
        elif e.key()==Qt.Key_Alt:
            self.setWindowTitle('按下Alt键')


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=OverrideSlot()
    main.show()
    sys.exit(app.exec_())

运行结果:

和注释一样。

我们通过覆盖keyPressEvent槽函数修改了按ESC和ALT键的行为。当我们按ESC的时候,窗口关闭,当按ALT键的时候窗口标题修改为"按下了Alt键"。

猜你喜欢

转载自blog.csdn.net/weixin_44593822/article/details/113810945