目录
一.为窗口添加信号
本质就是为一个类添加信号,只不过这个类是窗口类。
代码:
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_())
运行结果:
二.多线程更新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键"。