Introduction to PyQt5 (21) Signals and Slots (Medium)

table of Contents

1. Add a signal to the window

Two. Multithreading to update UI data

3. Automatically connect signals and slots

Four. Use Lambda expressions to pass parameters to slot functions

5. Use partial objects to pass parameters to slot functions

Six.override (override) slot function


1. Add a signal to the window

The essence is to add a signal to a class, but this class is a window class.

Code:

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_())

operation result:

 

Two. Multithreading to update UI data

Pass data in two threads.

Code:

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_())

operation result:

 

3. Automatically connect signals and slots

Code:

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_())

operation result:

 

 

Four. Use Lambda expressions to pass parameters to slot functions

Lambda expression: Anonymous function, that is, a function without a name.

Assign Lambda to a variable, and this variable becomes a function reference. Or pass the Lambda expression as a parameter to the function.

 

Code:

#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_())

operation result:

        

 

5. Use partial objects to pass parameters to slot functions

Code:

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_())

operation result:

The effect is the same as before, except that the partial class is used to pass the slot function.

 

Six.override (override) slot function

The system has defined many slot functions, we can override and rewrite these slot functions.

Code:

One thing to note: the function is the little camel case nomenclature! ! ! ! ! ! ! ! ! ! !

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_())

operation result:

Same as comments.

We modified the behavior of pressing the ESC and ALT keys by overriding the keyPressEvent slot function. When we press ESC, the window closes, and when we press the ALT key, the window title is changed to "Alt key pressed".

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_44593822/article/details/113810945