PythonPyQt5教程(二)按钮的封装及响应、窗口事件的监听
一、前言:
- 我们在上一章节初步接触了PyQt5的使用,实现了一个简单的GUI界面程序。
- PyQt5的功能非常强大,我们将一步一步来学习PyQt5中常用的一些控件。
- 如果PyQt5学好了,以后如果你有搞C++的时候需要使用Qt,变动将是非常小的。
二、编码实战
- 上次我们通过QWidget和QLable实现了一个简单的GUI程序,在lable上显示一句话。
- 其实,在PyQt5中,处于最外层的控件我们称为顶级窗口,任何窗口部件都可以作为顶级窗口。
- 控制顶级窗口的大小也就决定了我们程序界面的大小。
- 大多数情况下我们会用到QDialog或者QMainWindow,后面会讲到。
控件抽象
-
在上次我们是直接使用QWidget,然后通过设置QWidget的大小等,以及最后调用show来显示我们的组件。
-
本次我们将使用面向对象的方法来实现一个GUI程序。
-
代码如下:
import sys; from PyQt5.QtGui import *; from PyQt5.QtCore import *; from PyQt5.QtWidgets import *; class MyWindow(QWidget): def __init__(self): super(MyWindow, self).__init__(); self.initUI(); def initUI(self): rect = QRect(300, 300, 250, 250); self.setGeometry(rect) self.setWindowTitle('Windows Title'); self.show(); if __name__ == '__main__': app = QApplication(sys.argv); ex = MyWindow(); sys.exit(app.exec_());
-
OK,我们创建了一个继承QWidget的MyWindow类,然后在类实例话的时候调用initUI方法,在方法里设置窗口的一些参数。
-
运行效果如下
-
Ok,此时我想在窗口中间放一个按钮,监听我们的按钮点击事件。
-
代码修改:
import sys; from PyQt5.QtGui import *; from PyQt5.QtCore import *; from PyQt5.QtWidgets import *; class MyWindow(QWidget): def __init__(self): super(MyWindow, self).__init__(); self.initUI(); def click_Callback_one(self): print('click_Callback_one be called'); def click_Callback_two(self): print('click_Callback_two be called'); def initUI(self): rect = QRect(300, 300, 250, 250); self.setGeometry(rect) self.setWindowTitle('Windows Title'); qbtn = QPushButton(self); # 设置按钮的显示字样 qbtn.setText("Quit"); # 设置按钮大小,sizeHint()方法根据按钮内部的内容来为控件返回一个推荐的尺寸。 qbtn.resize(qbtn.sizeHint()); qbtn.move(50, 50); # PyQt5中的事件处理系统采用signal&slot(信号槽)机制。 # 当我们点击按钮时会发出clicked信号。slot可以是Qt slot或任何Python的callable对象。 qbtn.clicked.connect(self.click_Callback_one); #我们可以设置多个回调,他会按我们的设置顺序进行调用 qbtn.clicked.connect(self.click_Callback_two); self.show(); if __name__ == '__main__': app = QApplication(sys.argv); ex = MyWindow(); sys.exit(app.exec_());
-
界面效果如下:
-
点击之后输出如下:
click_Callback_one be called click_Callback_two be called
-
其按我们的设置顺序进行了调用。有关signal&slot(信号槽)机制后面会单独出一篇,这里我们只需要知道connect之后,当clicked被触发时,就会回调给我们。
-
OK,一个按钮我们就搞定了。
-
但是,此时,我希望点击时,关掉我们的窗口,那该如何实现呢?
-
其实很简单,我们只需要使用QCoreApplication对象。
-
QCoreApplication包含了主事件循环,它可以处理并分发事件。我们调用其退出程序的quit()方法即可关闭我们的窗口。
-
代码修改如下:
import sys; from PyQt5.QtGui import *; from PyQt5.QtCore import *; from PyQt5.QtWidgets import *; class MyWindow(QWidget): def __init__(self): super(MyWindow, self).__init__(); self.initUI(); def click_Callback_one(self): print('click_Callback_one be called'); # QCoreApplication包含了主事件循环;它可以处理并分发事件。 # instance()方法返回它的当前实例。 # QCoreApplication是由QApplication创建的。 # clicked信号连接到可以退出程序的quit()方法。 # 这个过程由两个对象完成:发送者与接收者。发送者是PushButton,接收者是QApplication对象。 QCoreApplication.instance().quit(); def click_Callback_two(self): print('click_Callback_two be called'); def initUI(self): rect = QRect(300, 300, 250, 250); self.setGeometry(rect) self.setWindowTitle('Windows Title'); qbtn = QPushButton(self); # 设置按钮的显示字样 qbtn.setText("Quit"); # 设置按钮大小,sizeHint()方法根据按钮内部的内容来为控件返回一个推荐的尺寸。 qbtn.resize(qbtn.sizeHint()); qbtn.move(50, 50); qbtn.clicked.connect(self.click_Callback_one); self.show(); if __name__ == '__main__': app = QApplication(sys.argv); ex = MyWindow(); sys.exit(app.exec_());
-
OK,此时你点击一下就会关闭我们的窗口了哦。
-
最后我们再添加个小功能,监听我们的窗口关闭按钮,在关闭的时候进行二次确认!我们只需要重写QWidget对象的closeEvent方法即可。
-
代码修改如下:
import sys; from PyQt5.QtGui import *; from PyQt5.QtCore import *; from PyQt5.QtWidgets import *; class MyWindow(QWidget): def __init__(self): super(MyWindow, self).__init__(); self.initUI(); def click_Callback_one(self): print('click_Callback_one be called'); QCoreApplication.instance().quit(); def click_Callback_two(self): print('click_Callback_two be called'); def initUI(self): rect = QRect(300, 300, 250, 250); self.setGeometry(rect) self.setWindowTitle('Windows Title'); qbtn = QPushButton(self); qbtn.setText("Quit"); qbtn.resize(qbtn.sizeHint()); qbtn.move(50, 50); qbtn.clicked.connect(self.click_Callback_one); self.show(); def closeEvent(self, event): print('我可能要被关闭了'); reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No); if reply == QMessageBox.Yes: event.accept() print('我被杀死了'); else: event.ignore() print('感谢不杀之恩'); if __name__ == '__main__': app = QApplication(sys.argv); ex = MyWindow(); sys.exit(app.exec_());
-
代码解析: 在关闭
QWidget
时会生成QCloseEvent
。然后就会回调我们的closeEvent函数。 -
QMessageBox设置为显示带有两个按钮(Yes和No)的消息对话框。第一个字符串会显示在标题栏,第二个字符串是对话框的消息文本。第三个参数设置了显示在对话框中的按钮。最后那个参数指定了默认的按钮,也就是默认取得键盘焦点的按钮。返回结果保存在
reply
变量中。 -
当点击了Yes按钮时,接受该事件且关闭该控件并退出程序;
-
点击No时,忽略这个关闭事件。