1. 认识 Signal 和 Slot
所有的应用都是事件驱动的。事件大部分都是由用户的行为产生的,例如鼠标点击,按下键盘等,当然也有其他的事件产生方式,比如网络的连接,窗口管理器或者定时器等。当某一事件发生时,就会发送对应的Signal,根据这个Signal连接的 Slot ,对应的处理也会被执行。大部分的部件也都内置了一些Slot(也可以理解为一些函数),但有时候我们想写一些自己的 Slot。
1.1 是谁发送了信号?
有时候我们需要知道是哪个部件发送了信号,我们可以通过 sender() 获得发送信号的部件,下面给出一个例子。
import sys
from PyQt5 import QtCore, QtWidgets
class Form(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
btn_1 = QtWidgets.QPushButton('Button 1', self)
btn_2 = QtWidgets.QPushButton('Button 2', self)
btn_1.move(50,30)
btn_2.move(150,30)
btn_1.clicked.connect(self.btn_click)
btn_2.clicked.connect(self.btn_click)
self.setGeometry(300, 300, 290, 150)
self.setWindowTitle('Event sender')
def btn_click(self):
sender = self.sender()
self.statusBar().showMessage('{} was pressed.'.format(sender.text()))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
form = Form()
form.show()
sys.exit(app.exec_())
运行结果:
1.2 如何发送信号?
很明显,我们同样需要知道需要发送信号。首先我们得知道 QObject 实例才可以发送信号。可以通过 QtCore.pyqySignal() 创建一个信号对象,但是要创建在 QObject 对象里。要不然 创建的信号是未绑定的。下面一个例子:
import sys
from PyQt5 import QtCore, QtWidgets
class Signal(QtCore.QObject):
#自定义信号,无参数
close_app = QtCore.pyqtSignal()
#自定义信号,有两个int 参数,信号名为 name = **
range_changed = QtCore.pyqtSignal(int, int, name='rangeChanged')
#参数为 int 或 QString
valueChanged = QtCore.pyqtSignal([int], ['QString'])
class TestSignal(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.c = Signal()
self.c.close_app.connect(self.close)
self.close_app = QtCore.pyqtSignal()
print(self.c.close_app)
print(self.close_app)
# close_app.connect(self.close)
self.setGeometry(300,300,100,100)
self.setWindowTitle('Emit signal')
self.show()
#重载鼠标点击事件
def mousePressEvent(self,e):
self.c.close_app.emit()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
form = TestSignal()
sys.exit(app.exec_())
上面代码也展示了如何自定义对象,以及如何发送信号,还有就是重载内置的事件。
2. 认识对话框
在GUI应用中对话框很常见,通常会用来确认一些信息。
对话框按模态进行分类:
- 应用程序模态对话框(弹出对话框后不能再与父级及以上部件交互,直至此会话完成)。
- 窗口模态对话框(弹出对话框后不能再与其他任何窗体或部件交互,直至此会话完成)。
- 非模态对话框(弹出对话框后还可以与其他部件交互,这种状态较难控制,但也常用,就像QQ聊天窗口。)
对话框的验证等级:
对于对话框输入的内容,我们有时候是需要验证的。
- 窗口部件级验证(域级验证),就是UI元素自身的验证。
- 窗体级验证,即域级验证满足不聊要求,常用于多个域之间的约束(例如注册时两次密码是否一致)。