table of Contents
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".