#信号与槽的N对N
from PyQt5.QtCore import *
class NtoNSignal(QObject):
signal1 = pyqtSignal() #定义信号
signal2 = pyqtSignal(int)
def __init__(self):
super().__init__()
self.signal1.connect(self.call1)
self.signal2.connect(self.call1) #signal1和signal2 同时绑定 call1 槽函数
self.signal2.connect(self.call2) #signal2 还绑定call2槽函数
self.signal1.emit() #触发
self.signal2.emit(2) #触发,调用call1的时候 ,这里的参数2没有用到
def call1(self): #槽函数
print('call1 emit')
def call2(self,value):
print('call2 emit:',value)
if __name__ == '__main__':
nnsignal = NtoNSignal()
#为窗口类添加信号
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class WindowDemo(QWidget):
mySignal = pyqtSignal()
def __init__(self):
super().__init__()
self.resize(400,300)
self.btn = QPushButton('quit')
layout = QVBoxLayout(self)
layout.addStretch(1)
layout.addWidget(self.btn)
self.mySignal.connect(self.mySlot) #这里创建我的信号,绑定我的槽,槽函数实现窗口关闭
self.btn.clicked.connect(self.btnClick) #这里button的的信号只能从他自己类里找
def btnClick(self):
self.mySignal.emit()
def mySlot(self):
self.close()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = WindowDemo()
main.show()
sys.exit(app.exec_())
#多线程更新UI数据
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
import sys
class MyThread(QThread):
update_datetime = pyqtSignal(str) #信号要带参数
def run(self):
while 1:
time.sleep(1)
date = QDateTime.currentDateTime()
currentTime = date.toString('yyyy-MM-dd hh:mm:ss')
self.update_datetime.emit(str(currentTime))
class MyWindow(QDialog):
def __init__(self):
QDialog.__init__(self)
self.resize(300,200)
self.setWindowTitle('多线程信号槽绑定')
self.initUI()
def initUI(self):
self.myThread = MyThread()
self.lineEdit = QLineEdit()
layout = QVBoxLayout(self)
layout.addWidget(self.lineEdit)
self.myThread.update_datetime.connect(self.updateTime)
self.myThread.start()
def updateTime(self,str_time):
self.lineEdit.setText(str_time)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MyWindow()
main.show()
sys.exit(app.exec_())
#信号和槽的自动连接 槽函数命名规则:on_objectName_signalName 比如 on_button1_clicked,这里必须设置button1的objectName为button1
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
import sys
class AutoSignalSlots(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('信号和槽自动连接')
self.resize(300,200)
self.initUI()
def initUI(self):
layout = QVBoxLayout(self)
self.btn1 = QPushButton('btn1')
self.btn1.setObjectName('button1') #设置Object name
self.btn2 = QPushButton('btn2')
self.btn2.setObjectName('button2')
layout.addWidget(self.btn1)
layout.addWidget(self.btn2)
QMetaObject.connectSlotsByName(self) #统一提示按照名字绑定槽
@pyqtSlot() #添加装饰器
def on_button1_clicked(self):
print('button1 clicked')
@pyqtSlot()
def on_button2_clicked(self):
print('button2 clicked')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = AutoSignalSlots()
main.show()
sys.exit(app.exec_())
#lambda 表达式为槽函数传递参数 :匿名函数,没有名字,以往绑定button的槽函数时都是,self.btn.clicked.connect(self.onBtnClicked),
#如果 onBtnClicked函数有参数呢?比如def onBtnClicked(self,x,y),这里又2个参数x,y,可以用lambda函数,写成下面的方式
# self.btn.cliced.connect(lambda:self.onBtnClicked(10,5))这样就可以了
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import time
import sys
class LambdaDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('lambda表达式为槽函数传递参数')
self.resize(300,200)
self.initUI()
def initUI(self):
layout = QVBoxLayout(self)
self.btn1 = QPushButton('btn1')
self.btn1.clicked.connect(lambda:self.onBtn1Clicked(10,5))
layout.addWidget(self.btn1)
def onBtn1Clicked(self,x,y):
QMessageBox.information(self,'结果',str(x+y))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = LambdaDemo()
main.show()
sys.exit(app.exec_())
#partial对象为槽函数传递参数
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from functools import partial
import time
import sys
class PartialDemo(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('partial为槽函数传递参数')
self.resize(300,200)
self.initUI()
def initUI(self):
layout = QVBoxLayout(self)
self.btn1 = QPushButton('btn1')
self.btn1.clicked.connect(partial(self.onBtn1Clicked,10,5)) #把self.onBtn1Clicked 作为partial的第一个参数,onBtn1Clicked的参数自动往后称为partial其他参数
layout.addWidget(self.btn1)
def onBtn1Clicked(self,x,y):
QMessageBox.information(self,'结果',str(x+y))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = PartialDemo()
main.show()
sys.exit(app.exec_())
#override(覆盖)槽函数
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
class Override(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('override(覆盖)槽函数')
def keyPressEvent(self,e): #覆盖了系统的槽函数 keyPressEvent
if e.key() == Qt.Key_Escape:
self.close()
elif e.key() == Qt.Key_Alt:
self.setWindowTitle('按下Alt键')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Override()
main.show()
sys.exit(app.exec_())
#多窗口交互【主窗口】
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
from MyDialog import Ui_Dialog
class MultiWindow(QWidget):
def __init__(self):
super().__init__()
self.resize(300,200)
self.setWindowTitle('多窗口交互')
self.initUI()
def initUI(self):
self.lineEdit = QLineEdit()
layout = QVBoxLayout(self)
self.btn = QPushButton('button1')
self.btn2 = QPushButton('button2')
layout.addWidget(self.lineEdit)
layout.addWidget(self.btn)
layout.addWidget(self.btn2)
self.btn.clicked.connect(self.btnClick)
self.btn2.clicked.connect(self.btn2Click)
def btnClick(self):
dialog = QDialog(self)
self.myDialog = Ui_Dialog()
self.myDialog.setupUi(dialog)
result = dialog.exec() #这里用exec 不用show
date = self.myDialog.getInfo()
if result == QDialog.Accepted:
self.lineEdit.setText(date.toString('yyyy-MM-dd'))
else:self.lineEdit.setText('没有选择日期')
dialog.destroy()
def btn2Click(self):
date,result = Ui_Dialog.getInfo_static()
if result == QDialog.Accepted:
self.lineEdit.setText(date.toString('yyyy-MM-dd'))
else:self.lineEdit.setText('没有做选择')
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MultiWindow()
main.show()
sys.exit(app.exec_())
#用ui自动生成的对话框 QDialog 带确认和取消的对话框
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Ui_Dialog(object): #这个ui用于获取日期,传递到主窗口中
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setGeometry(QtCore.QRect(30, 240, 341, 32))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.calendarWidget = QtWidgets.QCalendarWidget(Dialog)
self.calendarWidget.setGeometry(QtCore.QRect(30, 30, 331, 197))
self.calendarWidget.setObjectName("calendarWidget")
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
def getDate(self): #在ui类中创建一个要传递出去信息date的方法
return self.calendarWidget.selectedDate()
def getInfo(self):
return self.calendarWidget.selectedDate()
@staticmethod
def getInfo_static(): #创建静态方法,做实例化,并调用刚才创建的信息方法
dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(dialog)
result = dialog.exec() #对话框的执行
return (ui.getDate(),result == QtWidgets.QDialog.Accepted) #调用方法获取返回值