第十七章(第2节):常用界面功能

上一节末尾,我们写出了第一个界面程序,本节课开始,我们来学习常用的界面程序的写法,比如设置应用程序图标,弹出窗口,处理关闭消息,显示提示语等等。

编写应用程序图标

应用程序图标是一个小的图像,通常在标题栏的左上角显示,在下面的例子中我们将介绍如何做 pyqt5 的图标。

import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
class IconWidget(QWidget):
    def __init__(self):
        super().__init__()  # 调用父类 QWidget 的构造函数
        self.initUI()       # 界面绘制交给 InitUi 方法
    def initUI(self):
        # 设置窗口的位置和大小
        self.setGeometry(600, 200, 800, 500)
        # 设置窗口的标题
        self.setWindowTitle('图标')
        # 设置窗口的图标,确保当前目录下有 birdpython.png 图片
        self.setWindowIcon(QIcon('birdpython.png'))
        # 显示窗口
        self.show()
app = QApplication(sys.argv)   # 创建应用程序
ex = IconWidget()  # 创建窗口对象
app.exec_()        # 进入消息循环

显示提示语

提示语是在界面编程中非常实用的一项技术,用户的鼠标只要放在某个控件上,我们就可以显示一个提示语,给用户以解惑。

import sys
from PyQt5.QtWidgets import (QWidget, QToolTip,
                             QPushButton, QApplication)
from PyQt5.QtGui import QFont
class TooltipWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        # 这种静态的方法设置一个用于显示工具提示的字体。我们使用 10px 滑体字体。
        QToolTip.setFont(QFont('SansSerif', 10))
        # 当鼠标停留在该窗口内时,会弹出一个提示语
        self.setToolTip('这是 <b>老鸟python</b> 的 widget')
        # 创建一个 PushButton,当鼠标停留在该按钮上时,会弹出一个提示语
        btn = QPushButton('老鸟', self)
        btn.setToolTip('这是 <b>老鸟python</b> 的 button')
        # btn.sizeHint 显示默认尺寸
        btn.resize(btn.sizeHint())
        # 移动窗口的位置
        btn.move(50, 50)
        self.setGeometry(600, 200, 800, 500)
        self.setWindowTitle('提示语')
        self.show()
app = QApplication(sys.argv)
ex = TooltipWidget()
app.exec_()

关闭窗口

我们发现,前面的几个窗口例子,都是自带最小化,最大化和关闭功能,这些功能都是默认的。同样,我们也可以通过编程来关闭窗口。

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
from PyQt5.QtCore import QCoreApplication
class CloseWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        qbtn = QPushButton('退出', self)
        qbtn.clicked.connect(QCoreApplication.instance().quit)
        qbtn.resize(qbtn.sizeHint())
        qbtn.move(50, 50)
        self.setGeometry(600, 200, 800, 500)
        self.setWindowTitle('退出按钮')
        self.show()
app = QApplication(sys.argv)
ex = CloseWidget()
app.exec_()

消息框

默认情况下,如果我们单击 x按钮 窗口就关闭了。有时我们想修改这个默认的行为,例如我们在编辑器中修改了一个文件,当关闭他的时候,我们显示一个消息框确认。

import sys
from PyQt5.QtWidgets import QWidget, QMessageBox, QApplication
class MessageWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setGeometry(600, 200, 800, 500)
        self.setWindowTitle('消息框')
        self.show()
    def closeEvent(self, event):
        reply = QMessageBox.question(self, '消息',
                                     "你确定要退出吗?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
app = QApplication(sys.argv)
ex = MessageWidget()
app.exec_()

我们关闭窗口的时候,触发了 QCloseEvent。我们需要重写 closeEvent() 事件处理程序。

  reply = QMessageBox.question(self, '消息',
                                     "你确定要退出吗?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)

我们弹出一个消息框。上面函数第一个字符串是消息框的标题;第二个字符串消息对话框中显示的文本;第三个参数指定按钮的组合出现在对话框中,有两个按钮:“Yeas”和“No”;最后一个参数是默认按钮,这个是默认的按钮焦点。

if reply == QtGui.QMessageBox.Yes:
    event.accept()
else:
    event.ignore()

我们处理返回值,如果单击 Yes 按钮,关闭小部件并终止应用程序,否则我们忽略关闭事件,窗口亦然存在。

窗口显示在屏幕的中间

在前面的例子中,我们在程序中指定了窗口显示的位置,有时候我们希望窗口在屏幕中间显示,这个时候,就需要我们自己编程实现。

import sys
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication
class CenterWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        self.resize(800, 500)
        self.center()
        self.setWindowTitle('居中窗口')
        self.show()
    # 控制窗口显示在屏幕中心的方法
    def center(self):
        qr = self.frameGeometry()  # 获得窗口
        cp = QDesktopWidget().availableGeometry().center()  # 获得屏幕中心点
        qr.moveCenter(cp)  # 显示到屏幕中心
        self.move(qr.topLeft())
app = QApplication(sys.argv)
ex = CenterWidget()
app.exec_()

文档视窗和对话框

上面我们学习常用界面功能使用的都是 QWidget 部件,PyQt 还有另外两种部件,一个是 QMainWindow,QMainWindow 我们也叫文档视窗,典型的基于 QMainWindow 的应用程序有记事本,Word 等等;另一个是 QDialog,QDialog 我们也叫对话框,典型的基于对话框的应用程序有 QQ,360 等等。

基于 QMainWindow 的开发,我们很少用到,而 QDialog 和 QWidget 很类似,我们普遍都使用 QWidget 来代替对话框。下面我们就分别学习一下如何编写基于文档视窗和对话框的应用程序。

下面我们开发一个文档视窗图形界面应用程序,你用它可以让应用程序添加状态栏,工具栏和菜单栏等等视窗常有的属性。

import sys
from PyQt5.QtWidgets import QMainWindow, QTextEdit, QAction, QApplication
from PyQt5.QtGui import QIcon
class myWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        textEdit = QTextEdit()
        self.setCentralWidget(textEdit)
        exitAction = QAction(QIcon('birdpython.png'), '退出', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('退出程序')
        exitAction.triggered.connect(self.close)
        self.statusBar()
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&文件')
        fileMenu.addAction(exitAction)
        toolbar = self.addToolBar('退出')
        toolbar.addAction(exitAction)
        self.setGeometry(600, 200, 800, 500)
        self.setWindowTitle('文档视窗')
        self.show()
app = QApplication(sys.argv)
ex = myWindow()
app.exec_()

下面我们创建一个对话框图形界面应用程序,大家可以看到编写对话框程序和 编写 QWidget 基本没什么区别。

import sys
from PyQt5.QtWidgets import QApplication, QDialog
class myDialog(QDialog):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        self.setGeometry(600, 200, 800, 500)