目录

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方法,在方法里设置窗口的一些参数。

  • 运行效果如下 http://upload-images.jianshu.io/upload_images/1811893-8b6423ea4674fe54.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

  • 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_());
    
  • 界面效果如下:

http://upload-images.jianshu.io/upload_images/1811893-ff4009cf52dde820.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

  • 点击之后输出如下:

      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时,忽略这个关闭事件。