本专栏内容为:Python学习专栏 通过本专栏的深入学习,你可以了解并掌握Python。
💓博主csdn个人主页:小小unicorn
⏩专栏分类:Python
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识
目录
- PYQT5
- helloworld
- PYQT5主要类
- 使用qt设计器
- 信号与槽
- 使用 Qt Designer 的 Signal/Slot 编辑器
- 建立Signal-slot 连接
- 示例
- 布局管理
- setGeometry语法
- QBoxLayout 类
- **GridLayout** 类
- **QFormLayout类**
- **QDialog类**
- **QMessageBox** 类
- 多文档界面
- Brush 样式常量
- Brush 样式常量
- 预定义的 QColor 样式
- 预定义的 QColor 对象
- **QClipboard**
- **QPixmap**
PYQT5
helloworld
使用 PyQt 创建一个简单的 GUI 应用程序涉及以下步骤 −
- 从 PyQt5 包中导入 QtCore、QtGui 和 QtWidgets 模块。
- 创建一个QApplication类的应用对象。
- QWidget 对象创建顶级窗口。 在其中添加 QLabel 对象。
- 设置label的标题为"hello world"。
- 通过setGeometry()方法定义窗口的大小和位置。
- 通过**app.exec_()**方法进入应用程序的主循环。
以下是在 PyQt 中执行 Hello World 程序的代码 −
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():app=QApplication(sys.argv)w=QWidget()b=QLabel(w)b.setText("PYQT5")w.setGeometry(200,200,600,500)b.move(50,20)w.setWindowTitle("PyQt5")w.show()sys.exit(app.exec_())
if __name__ == '__main__':window()
也可以开发上述代码的面向对象的解决方案。
- 从 PyQt5 包中导入 QtCore、QtGui 和 QtWidgets 模块。
- 创建一个QApplication类的应用对象。
- 基于QWidget类声明窗口类
- 添加一个QLabel对象,并将label的标题设置为"hello world"。
- 通过setGeometry()方法定义窗口的大小和位置。
- 通过**app.exec_()**方法进入应用程序的主循环。
以下是面向对象解决方案的完整代码 −
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class window(QWidget):def __init__(self, parent = None):super(window, self).__init__(parent)self.resize(200,50)self.setWindowTitle("PyQt5")self.label = QLabel(self)self.label.setText("Hello World")font = QFont()font.setFamily("Arial")font.setPointSize(16)self.label.setFont(font)self.label.move(50,20)
def main():app = QApplication(sys.argv)ex = window()ex.show()sys.exit(app.exec_())
if __name__ == '__main__':main()
PYQT5主要类
PyQt API 是一个大类和方法的集合。 这些类在 20 多个模块中定义。
以下是一些常用的模块 −
序号 | 模块 & 说明 |
---|---|
1 | QtCore其他模块使用的核心非 GUI 类 |
2 | QtGui图形用户界面组件 |
3 | QtMultimedia低级多媒体编程类 |
4 | QtNetwork网络编程类 |
5 | QtOpenGLOpenGL 支持类 |
6 | QtScript用于评估 Qt 脚本的类 |
7 | QtSql使用 SQL 进行数据库集成的类 |
8 | QtSvg显示 SVG 文件内容的类 |
9 | QtWebKit用于呈现和编辑 HTML 的类 |
10 | QtXml处理 XML 的类 |
11 | QtWidgets用于创建经典桌面样式 UI 的类。 |
12 | QtDesigner用于扩展 Qt Designer 的类 |
13 | QtAssistant支持在线帮助 |
PyQt5 开发工具是用于 Qt 开发的有用实用程序的集合。 以下是此类实用程序的精选列表 −
序号 | 工具名称 & 说明 |
---|---|
1 | assistantQt Assistant 文档工具 |
2 | pyqt5designerQt Designer GUI 布局工具 |
3 | linguistQt Linguist 翻译工具 |
4 | lrelease将ts文件编译成qm文件 |
5 | pylupdate5提取翻译字符串并生成或更新 ts 文件 |
6 | qmakeQt 软件构建工具 |
7 | pyqt5qmlsceneQML 文件查看器 |
8 | pyqmlviewerQML 文件查看器 |
9 | pyrcc5Qt资源文件编译器 |
10 | pyuic5用于从 ui 文件生成代码的 Qt 用户界面编译器 |
11 | pyqmltestrunner在 QML 代码上运行单元测试 |
12 | qdbus列出 D-Bus 服务的命令行工具 |
13 | QDocd软件项目的文档生成器。 |
14 | Qhelpgenerator生成和查看 Qt 帮助文件。 |
15 | qmlimportscanner解析和报告 QML 导入 |
PyQt API 包含 400 多个类。 QObject 类位于类层次结构的顶部。 它是所有 Qt 对象的基类。 此外,QPaintDevice 类是所有可绘制对象的基类。
QApplication 类管理 GUI 应用程序的主要设置和控制流程。 它包含主事件循环,在其中处理和调度由窗口元素和其他源生成的事件。 它还处理系统范围和应用程序范围的设置。
QWidget 类,派生自 QObject 和 QPaintDevice 类,是所有用户界面对象的基类。 QDialog 和 QFrame 类也派生自 QWidget 类。 他们有自己的子类系统。
这里是常用小部件的选择列表
序号 | 小部件和描述 |
---|---|
1 | QLabel用于显示文本或图像 |
2 | QLineEdit允许用户输入一行文本 |
3 | QTextEdit允许用户输入多行文本 |
4 | QPushButton调用操作的命令按钮 |
5 | QRadioButton允许从多个选项中选择一个 |
6 | QCheckBox允许选择多个选项 |
7 | QSpinBox允许增加/减少整数值 |
8 | QScrollBar允许访问超出显示孔径的小部件的内容 |
9 | QSlider允许线性改变边界值。 |
10 | QComboBox提供可供选择的项目的下拉列表 |
11 | QMenuBar持有 QMenu 对象的水平条 |
12 | QStatusBar通常在 QMainWindow 的底部,提供状态信息。 |
13 | QToolBar通常在 QMainWindow 顶部或浮动。 包含操作按钮 |
14 | QListView在 ListMode 或 IconMode 中提供可选择的项目列表 |
15 | QPixmap显示在 QLabel 或 QPushButton 对象上的屏幕外图像表示 |
16 | QDialog****可以向父窗口返回信息的模态或非模态窗口 |
一个典型的基于 GUI 的应用程序的顶级窗口是由 QMainWindow 小部件对象创建的。 上面列出的一些小部件在此主窗口中占据指定位置,而其他小部件则使用各种布局管理器放置在中央小部件区域。
下图展示了QMainWindow框架 −
使用qt设计器
PyQt 安装程序带有一个名为 Qt Designer 的 GUI 构建器工具。 使用其简单的拖放界面,无需编写代码即可快速构建 GUI 界面。 但是,它不是诸如 Visual Studio 之类的 IDE。 因此,Qt Designer 不具备调试和构建应用程序的功能。
启动 Qt Designer 应用程序,它是开发工具的一部分,安装在虚拟环境的脚本文件夹中。
通过选择 File → New 菜单开始设计 GUI 界面.
可以从左侧窗格的小部件框中拖放所需的小部件。 您还可以为表单上放置的小部件的属性分配值。
设计好的表格保存为demo.ui。 此 ui 文件包含设计中的小部件及其属性的 XML 表示。 使用 pyuic5 命令行实用程序将此设计转换为 Python 等效项。 该实用程序是 Qt 工具包的 uic 模块的包装器。 pyuic5的用法如下 −
pyuic5 -x demo.ui -o demo.py
在上述命令中,-x 开关向生成的 Python 脚本(来自 XML)添加了少量附加代码,使其成为可自执行的独立应用程序。
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'test.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(1018, 779)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(170, 130, 171, 81))self.pushButton.setObjectName("pushButton")self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)self.lineEdit.setGeometry(QtCore.QRect(500, 240, 171, 61))self.lineEdit.setObjectName("lineEdit")self.textEdit = QtWidgets.QTextEdit(self.centralwidget)self.textEdit.setGeometry(QtCore.QRect(110, 290, 251, 121))self.textEdit.setObjectName("textEdit")self.timeEdit = QtWidgets.QTimeEdit(self.centralwidget)self.timeEdit.setGeometry(QtCore.QRect(730, 390, 171, 61))self.timeEdit.setObjectName("timeEdit")self.timeEdit_2 = QtWidgets.QTimeEdit(self.centralwidget)self.timeEdit_2.setGeometry(QtCore.QRect(710, 100, 181, 61))self.timeEdit_2.setObjectName("timeEdit_2")self.dateTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)self.dateTimeEdit.setGeometry(QtCore.QRect(280, 20, 241, 61))self.dateTimeEdit.setObjectName("dateTimeEdit")self.label = QtWidgets.QLabel(self.centralwidget)self.label.setGeometry(QtCore.QRect(200, 490, 221, 71))self.label.setObjectName("label")self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)self.textBrowser.setGeometry(QtCore.QRect(450, 470, 321, 201))self.textBrowser.setObjectName("textBrowser")MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 1018, 27))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.pushButton.setText(_translate("MainWindow", "PushButton"))self.label.setText(_translate("MainWindow", "TextLabel"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())
信号与槽
与以顺序方式执行的控制台模式应用程序不同,基于 GUI 的应用程序是事件驱动的。 函数或方法响应用户的操作(例如单击按钮、从集合中选择项目或单击鼠标等)执行,称为 events。
用于构建 GUI 界面的小部件充当此类事件的来源。 每个派生自 QObject 类的 PyQt 小部件都旨在发出 “信号” 以响应一个或多个事件。信号本身不执行任何操作。 相反,它"连接"到一个**“插槽”。 插槽可以是任何可调用的 Python 函数**。
使用 Qt Designer 的 Signal/Slot 编辑器
首先设计一个带有 LineEdit 控件和 PushButton 的简单表单。
希望如果按下按钮,文本框的内容应该被删除。 QLineEdit 小部件为此目的有一个 clear() 方法。 因此,按钮的 clicked 信号将连接到文本框的 clear() 方法。
首先,从 Edit 菜单中选择 Edit signals/slots(或按 F4)。 然后用鼠标突出显示按钮并将光标拖向文本框
释放鼠标时,将显示一个对话框,显示按钮 Signal 和 Slot 方法。 选择 clicked 信号和 clear() 方法
右下角的 Signal/Slot 编辑器窗口将显示结果 −
从 ui 文件中保存 ui 和 Build 和 Python 代码,如下面的代码所示 −
pyuic5 -x signalslot.ui -o signalslot.py
python代码如下:
# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'signalslot.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(894, 711)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)self.lineEdit.setGeometry(QtCore.QRect(240, 70, 331, 71))self.lineEdit.setObjectName("lineEdit")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(240, 200, 331, 91))self.pushButton.setObjectName("pushButton")MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 894, 27))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)self.pushButton.clicked.connect(self.lineEdit.clear) # type: ignoreQtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.pushButton.setText(_translate("MainWindow", "PushButton"))if __name__ == "__main__":import sysapp = QtWidgets.QApplication(sys.argv)MainWindow = QtWidgets.QMainWindow()ui = Ui_MainWindow()ui.setupUi(MainWindow)MainWindow.show()sys.exit(app.exec_())
生成的 Python 代码将通过以下语句在信号和插槽之间建立联系 −
self.pushButton.clicked.connect(self.lineEdit.clear)
运行 signalslot.py 并在 LineEdit 中输入一些文本。 如果按下按钮,文本将被清除。
点击后被删除:
建立Signal-slot 连接
您可以不使用Designer,而是通过以下语法直接建立 Signal-slot 连接 −
widget.signal.connect(slot_function)
假设单击按钮时是否要调用函数。 在这里,clicked 信号将连接到一个可调用函数。 它可以通过以下任何一种技术来实现 −
button.clicked.connect(slot_function)
示例
在以下示例中,在 QDialog 窗口中添加了两个 QPushButton 对象(b1 和 b2)。 我们想分别在单击 b1 和 b2 时调用函数 b1_clicked() 和 b2_clicked()。
当b1被点击时,clicked()信号连接到b1_clicked()函数 −
b1.clicked.connect(b1_clicked())
单击 b2 时,clicked() 信号连接到 b2_clicked() 函数。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)win = QDialog()b1 = QPushButton(win)b1.setText("Button1")b1.move(50,20)b1.clicked.connect(b1_clicked)b2 = QPushButton(win)b2.setText("Button2")b2.move(50,50)b2.clicked.connect(b2_clicked)win.setGeometry(100,100,200,100)win.setWindowTitle("PyQt5")win.show()sys.exit(app.exec_())def b1_clicked():print ("Button 1 clicked")def b2_clicked():print ("Button 2 clicked")if __name__ == '__main__':window()
运行结果:
布局管理
通过指定以像素为单位的绝对坐标,可以将 GUI 小部件放置在容器窗口内。 坐标相对于 setGeometry() 方法定义的窗口尺寸。
setGeometry语法
QWidget.setGeometry(xpos, ypos, width, height)
在以下代码片段中,尺寸为 300 x 200 像素的顶级窗口显示在监视器上的位置 (10, 10)。
import sys
from PyQt4 import QtGuidef window():app = QtGui.QApplication(sys.argv)w = QtGui.QWidget()b = QtGui.QPushButton(w)b.setText("Hello World!")b.move(50,20)w.setGeometry(10,10,300,200)w.setWindowTitle(“PyQt”)w.show()sys.exit(app.exec_())if __name__ == '__main__':window()
PushButton 小部件被添加到窗口中,并放置在窗口右侧 50 像素和左上角下方 20 像素的位置。
但是,由于以下原因,此绝对定位不适合 −
- 即使调整窗口大小,小部件的位置也不会改变。
- 在不同分辨率的不同显示设备上,外观可能不统一。
- 布局的修改很困难,因为它可能需要重新设计整个表单。
PyQt API 提供布局类,以便更优雅地管理容器内的小部件定位。 布局管理器相对于绝对定位的优势是 −
- 窗口内的小部件会自动调整大小。
- 确保在不同分辨率的显示设备上呈现统一的外观。
- 无需重新设计即可动态添加或删除小部件。
Qt 工具包定义了可以与 Qt Designer 实用程序一起使用的各种布局。
这是我们将在本章中一一讨论的类列表。
序号 | 类 & 描述 |
---|---|
1 | QBoxLayout QBoxLayout 类垂直或水平排列小部件。 它的派生类是 QVBoxLayout(用于垂直排列小部件)和 QHBoxLayout(用于水平排列小部件)。 |
2 | QGridLayout GridLayout 类对象呈现以行和列排列的单元格网格。 该类包含 addWidget() 方法。 通过指定单元格的行数和列数,可以添加任何小部件。 |
3 | QFormLayout QFormLayout 是一种创建两列表单的便捷方式,其中每一行包含一个与标签关联的输入字段。 按照惯例,左列包含标签,右列包含输入字段。 |
QBoxLayout 类
QBoxLayout 类垂直或水平排列小部件。 它的派生类是QVBoxLayout(用于垂直排列小部件)和QHBoxLayout(用于水平排列小部件)。 下表显示了 QBoxLayout 类的重要方法 −
序号 | 方法 & 说明 |
---|---|
1 | **addWidget()**将小部件添加到 BoxLayout |
2 | **addStretch()**创建空的可拉伸框 |
3 | **addLayout()**添加另一个嵌套布局 |
示例1:
这里在垂直框布局中添加了两个按钮。 通过 addStretch() 方法在它们之间添加一个可拉伸的空白空间。 因此,如果调整顶层窗口的大小,按钮的位置会自动重新定位。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)win = QWidget()b1 = QPushButton("Button1")b2 = QPushButton("Button2")vbox = QVBoxLayout()vbox.addWidget(b1)vbox.addStretch()vbox.addWidget(b2)win.setLayout(vbox)win.setWindowTitle("PyQt")win.show()sys.exit(app.exec_())if __name__ == '__main__':window()
运行结果:
示例2:
此示例使用水平框布局。 addStretch() 方法在两个按钮对象之间插入一个可拉伸的空白区域。 因此,随着窗口大小的调整,按钮的大小和位置会动态变化。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def window():app = QApplication(sys.argv)win = QWidget()b1 = QPushButton("Button1")b2 = QPushButton("Button2")hbox = QHBoxLayout()hbox.addWidget(b1)hbox.addStretch()hbox.addWidget(b2)win.setLayout(hbox)win.setWindowTitle("PyQt")win.show()sys.exit(app.exec_())
if __name__ == '__main__':window()
示例3:
此示例显示如何嵌套布局。 在这里,两个按钮被添加到垂直框布局中。 然后,添加了一个带有两个按钮和一个可拉伸空白区域的水平框布局对象。 最后,通过 setLayout() 方法将垂直框布局对象应用到顶层窗口。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)win = QWidget()b1 = QPushButton("Button1")b2 = QPushButton("Button2")vbox = QVBoxLayout()vbox.addWidget(b1)vbox.addStretch()vbox.addWidget(b2)hbox = QHBoxLayout()b3 = QPushButton("Button3")b4 = QPushButton("Button4")hbox.addWidget(b3)hbox.addStretch()hbox.addWidget(b4)vbox.addStretch()vbox.addLayout(hbox)win.setLayout(vbox)win.setWindowTitle("PyQt")win.show()sys.exit(app.exec_())
if __name__ == '__main__':window()
运行结果:
GridLayout 类
GridLayout 类对象以行和列排列的单元格网格呈现。 该类包含 addWidget() 方法。 通过指定单元格的行数和列数,可以添加任何小部件。 (可选)行和列的跨度因子(如果指定)使小部件比一个单元格更宽或更高。 addWidget() 方法的两个重载如下 −
序号 | 方法 & 说明 |
---|---|
1 | **addWidget(QWidget, int r, int c)**在指定的行和列添加一个小部件 |
2 | **addWidget(QWidget, int r, int c, int rowspan, int columnspan)**在指定的行和列添加一个小部件,并具有指定的宽度和/或高度 |
也可以在网格中的任何单元格中添加子布局对象
序号 | 方法 & 说明 |
---|---|
1 | **addLayout(QLayout, int r, int c)**在指定的行和列添加布局对象 |
示例:
以下代码创建了一个由 16 个按钮组成的网格布局,这些按钮以 4 行 4 列的网格布局排列
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)win = QWidget()grid = QGridLayout()for i in range(1,5):for j in range(1,5):grid.addWidget(QPushButton("B"+str(i)+str(j)),i,j)win.setLayout(grid)win.setGeometry(100,100,200,100)win.setWindowTitle("PyQt")win.show()sys.exit(app.exec_())if __name__ == '__main__':window()
该代码对行号和列号使用两个嵌套的 for 循环,由变量 i 和 j 表示。它们被转换为字符串以连接要添加到 i行和 j 列的每个按钮的标题。
运行结果:
QFormLayout类
QFormLayout 是一种创建两列表单的便捷方式,其中每一行包含一个与标签关联的输入字段。 按照惯例,左列包含标签,右列包含输入字段。 主要是常用的**addRow()**方法addLayout()的三个重载。
序号 | 方法 & 说明 |
---|---|
1 | **addRow(QLabel, QWidget)**添加包含标签和输入字段的行 |
2 | **addRow(QLabel, QLayout)**在第二列中添加子布局 |
3 | **addRow(QWidget)**添加一个跨越两列的小部件 |
示例:
此代码添加一个 LineEdit 字段以在第一行输入名称。 然后它为下一行的第二列中的两个地址字段添加垂直框布局。 接下来,在第三行的第二列中添加一个包含两个单选按钮字段的水平框布局对象。 第四行显示两个按钮"Submit"和"Cancel"。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)win = QWidget()l1 = QLabel("Name")nm = QLineEdit()l2 = QLabel("Address")add1 = QLineEdit()add2 = QLineEdit()fbox = QFormLayout()fbox.addRow(l1,nm)vbox = QVBoxLayout()vbox.addWidget(add1)vbox.addWidget(add2)fbox.addRow(l2,vbox)hbox = QHBoxLayout()r1 = QRadioButton("Male")r2 = QRadioButton("Female")hbox.addWidget(r1)hbox.addWidget(r2)hbox.addStretch()fbox.addRow(QLabel("sex"),hbox)fbox.addRow(QPushButton("Submit"),QPushButton("Cancel"))win.setLayout(fbox)win.setWindowTitle("PyQt")win.show()sys.exit(app.exec_())if __name__ == '__main__':window()
运行结果:
QDialog类
QDialog 小部件呈现一个顶级窗口,主要用于收集用户的响应。 它可以配置为 Modal(它会阻止其父窗口)或 Modeless(可以绕过对话窗口)。
PyQt API 有许多预配置的 Dialog 小部件,例如 InputDialog、FileDialog、FontDialog 等。
示例:
在下面的例子中,Dialog 窗口的 WindowModality 属性决定了它是模态的还是非模态的。 对话框上的任何一个按钮都可以设置为默认值。 当用户按下 Escape 键时,该对话框被 QDialog.reject() 方法丢弃。
顶级QWidget窗口上的PushButton,当点击时,会产生一个Dialog窗口。 对话框的标题栏上没有最小化和最大化控件。
用户无法在后台将此对话框降级,因为它的 WindowModality 设置为 ApplicationModal。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)w = QWidget()btn = QPushButton(w)btn.setText("Hello World!")btn.move(100,50)btn.clicked.connect(showdialog)w.setWindowTitle("PyQt Dialog demo")w.show()sys.exit(app.exec_())def showdialog():dlg = QDialog()b1 = QPushButton("ok",dlg)b1.move(50,50)dlg.setWindowTitle("Dialog") 9. PyQt5 — QDialog Classdlg.setWindowModality(Qt.ApplicationModal)dlg.exec_()if __name__ == '__main__':window()
运行结果:
QMessageBox 类
QMessageBox 是一种常用的模式对话框,用于显示一些信息性消息,并可选择要求用户通过单击其上的任何一个标准按钮来做出响应。 每个标准按钮都有一个预定义的标题、一个角色并返回一个预定义的十六进制数字。
与QMessageBox类相关的重要方法和枚举如下表所示 −
序号 | 方法 & 说明 |
---|---|
1 | **setIcon()**显示与消息严重性相对应的预定义图标问题信息警告严重 |
2 | **setText()**设置要显示的主要消息的文本 |
3 | **setInformativeText()**显示附加信息 |
4 | **setDetailText()**对话框显示一个详细信息按钮。 此文本在单击时出现 |
5 | **setTitle()**显示对话框的自定义标题 |
6 | **setStandardButtons()**要显示的标准按钮列表。 每个按钮都与QMessageBox.Ok 0x00000400QMessageBox.Open 0x00002000QMessageBox.Save 0x00000800QMessageBox.Cancel 0x00400000QMessageBox.Close 0x00200000QMessageBox.Yes 0x00004000QMessageBox.No 0x00010000QMessageBox.Abort 0x00040000QMessageBox.Retry 0x00080000QMessageBox.Ignore 0x00100000 |
7 | **setDefaultButton()**将按钮设置为默认值。 如果按下 Enter,它会发出 clicked 信号 |
8 | **setEscapeButton()**设置按钮在按下退出键时被视为单击 |
示例:
在下面的例子中,点击顶层窗口按钮的信号,连接的函数显示消息框对话框。
msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("This is a message box")
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
msg.setDetailedText("The details are as follows:")
setStandardButton() 函数显示所需的按钮。
msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
buttonClicked() 信号连接到一个槽函数,该函数标识信号源的标题。
msg.buttonClicked.connect(msgbtn)
完整示例代码:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)w = QWidget()b = QPushButton(w)b.setText("Show message!")b.move(100,50)b.clicked.connect(showdialog)w.setWindowTitle("PyQt MessageBox demo")w.show()sys.exit(app.exec_())def showdialog():msg = QMessageBox()msg.setIcon(QMessageBox.Information)msg.setText("This is a message box")msg.setInformativeText("This is additional information")msg.setWindowTitle("MessageBox demo")msg.setDetailedText("The details are as follows:")msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)msg.buttonClicked.connect(msgbtn)retval = msg.exec_()def msgbtn(i):print ("Button pressed is:",i.text())if __name__ == '__main__':window()
运行结果:
如果单击 MessageBox 上的 Ok 或 Cancel 按钮,控制台上会产生以下输出 −
Button pressed is: OK
Button pressed is: Cancel
多文档界面
一个典型的 GUI 应用程序可能有多个窗口。 选项卡式和堆叠式小部件允许一次激活一个这样的窗口。 然而,很多时候这种方法可能没有用,因为其他窗口的视图被隐藏了。
同时显示多个窗口的一种方法是将它们创建为独立的窗口。 这称为 SDI (单文档接口)。 这需要更多的内存资源,因为每个窗口可能有自己的菜单系统、工具栏等。
MDI (多文档接口) 应用程序消耗较少的内存资源。 子窗口相对于彼此放置在主容器内。 容器小部件称为 QMdiArea。
QMdiArea 小部件一般占据 QMainWondow 对象的中心小部件。 该区域中的子窗口是 QMdiSubWindow 类的实例。 可以将任何 QWidget 设置为 subWindow 对象的内部小部件。 MDI区域的子窗口可以层叠或平铺排列。
下表列出了QMdiArea类和QMdiSubWindow类的重要方法 −
序号 | 方法 & 说明 |
---|---|
1 | **addSubWindow()**在 MDI 区域中添加一个小部件作为新的子窗口 |
2 | **removeSubWindow()**删除作为子窗口内部小部件的小部件 |
3 | **setActiveSubWindow()**激活子窗口 |
4 | **cascadeSubWindows()**以级联方式排列 MDiArea 中的子窗口 |
5 | **tileSubWindows()**以平铺方式排列 MDiArea 中的子窗口 |
6 | **closeActiveSubWindow()**关闭活动子窗口 |
7 | **subWindowList()**返回 MDI 区域中的子窗口列表 |
8 | **setWidget()**将 QWidget 设置为 QMdiSubwindow 实例的内部小部件 |
QMdiArea 对象发出 subWindowActivated() 信号,而 windowStateChanged() 信号由 QMdisubWindow 对象发出。
示例:
在下面的示例中,由 QMainWindow 组成的顶级窗口有一个菜单和 MdiArea。
self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")
菜单的 Triggered() 信号连接到 windowaction() 函数。
file.triggered[QAction].connect(self.windowaction)
menu 的新动作在 MDI 区域中添加了一个子窗口,其标题具有递增编号。
MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()
菜单的级联和平铺按钮分别以级联和平铺方式排列当前显示的子窗口。
完整代码如下 −
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *class MainWindow(QMainWindow):count = 0def __init__(self, parent = None):super(MainWindow, self).__init__(parent)self.mdi = QMdiArea()self.setCentralWidget(self.mdi)bar = self.menuBar()file = bar.addMenu("File")file.addAction("New")file.addAction("cascade")file.addAction("Tiled")file.triggered[QAction].connect(self.windowaction)self.setWindowTitle("MDI demo")def windowaction(self, q):print ("triggered")if q.text() == "New":MainWindow.count = MainWindow.count+1sub = QMdiSubWindow()sub.setWidget(QTextEdit())sub.setWindowTitle("subwindow"+str(MainWindow.count))self.mdi.addSubWindow(sub)sub.show()if q.text() == "cascade":self.mdi.cascadeSubWindows()if q.text() == "Tiled":self.mdi.tileSubWindows()def main():app = QApplication(sys.argv)ex = MainWindow()ex.show()sys.exit(app.exec_())if __name__ == '__main__':main()
以层叠和平铺的形式运行上面的代码和三个窗口 −
Brush 样式常量
Brush 样式常量
以下是 Brush 样式常量 −
Qt.NoBrush | No brush pattern |
---|---|
Qt.SolidPattern | Uniform color |
Qt.Dense1Pattern | Extremely dense brush pattern |
Qt.HorPattern | Horizontal lines |
Qt.VerPattern | Vertical lines |
Qt.CrossPattern | Crossing horizontal and vertical lines |
Qt.BDiagPattern | Backward diagonal lines |
Qt.FDiagPattern | Forward diagonal lines |
Qt.DiagCrossPattern | Crossing diagonal lines |
预定义的 QColor 样式
下面给出的是预定义的 QColor 样式 −
Qt.NoBrush | No brush pattern |
---|---|
Qt.SolidPattern | Uniform color |
Qt.Dense1Pattern | Extremely dense brush pattern |
Qt.HorPattern | Horizontal lines |
Qt.VerPattern | Vertical lines |
Qt.CrossPattern | Crossing horizontal and vertical lines |
Qt.BDiagPattern | Backward diagonal lines |
Qt.FDiagPattern | Forward diagonal lines |
Qt.DiagCrossPattern | Crossing diagonal lines |
预定义的 QColor 对象
下面给出的是预定义的 QColor 对象 −
Qt.white |
---|
Qt.black |
Qt.red |
Qt.darkRed |
Qt.green |
Qt.darkGreen |
Qt.blue |
Qt.cyan |
Qt.magenta |
Qt.yellow |
Qt.darkYellow |
Qt.gray |
可以通过指定 RGB 或 CMYK 或 HSV 值来选择自定义颜色。
QClipboard
QClipboard 类提供对系统范围剪贴板的访问,该剪贴板提供了一种在应用程序之间复制和粘贴数据的简单机制。 它的作用类似于 QDrag 类并使用相似的数据类型。
QApplication 类有一个静态方法 clipboard(),它返回对剪贴板对象的引用。 任何类型的 MimeData 都可以复制到剪贴板或从剪贴板粘贴。
以下是常用的剪贴板类方法 −
序号 | 方法 & 说明 |
---|---|
1 | **clear()**清除剪贴板内容 |
2 | **setImage()**将 QImage 复制到剪贴板 |
3 | **setMimeData()**将 MIME 数据设置到剪贴板 |
4 | **setPixmap()**复制剪贴板中的像素图对象 |
5 | **setText()**在剪贴板中复制 QString |
6 | **text()**从剪贴板中检索文本 |
与剪贴板对象关联的信号是 −
序号 | 方法 & 说明 |
---|---|
1 | **dataChanged()**每当剪贴板数据发生变化 |
示例:
在以下示例中,将两个 TextEdit 对象和两个 Pushbuttons 添加到顶级窗口。
首先实例化剪贴板对象。 textedit 对象的 Copy() 方法将数据复制到系统剪贴板上。 单击"粘贴"按钮时,它会获取剪贴板数据并将其粘贴到其他文本编辑对象中。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *class Example(QWidget):def __init__(self):super(Example, self).__init__()self.initUI()def initUI(self):hbox = QVBoxLayout()self.edit1=QTextEdit()hbox.addWidget(self.edit1)self.btn1=QPushButton("Copy")hbox.addWidget(self.btn1)self.edit2=QTextEdit()self.btn2=QPushButton("Paste")hbox.addWidget(self.edit2)hbox.addWidget(self.btn2)self.btn1.clicked.connect(self.copytext)self.btn2.clicked.connect(self.pastetext)self.setLayout(hbox)self.setGeometry(300, 300, 300, 200)self.setWindowTitle('Clipboard')self.show()def copytext(self):#clipboard.setText(self.edit1.copy())self.edit1.copy()print (clipboard.text())msg=QMessageBox()msg.setText(clipboard.text()+" copied on clipboard")msg.exec_()def pastetext(self):self.edit2.setText(clipboard.text())app = QApplication(sys.argv)
clipboard=app.clipboard()
ex = Example()
ex.setWindowTitle("clipboard Example")
sys.exit(app.exec_())
QPixmap
QPixmap 类提供图像的离屏表示。 它可以用作 QPaintDevice 对象,也可以加载到另一个小部件中,通常是标签或按钮。
Qt API 有另一个类似的类 QImage,它针对 I/O 和其他像素操作进行了优化。 另一方面,Pixmap 针对在屏幕上显示进行了优化。 两种格式都可以相互转换。
QPixmap对象可以读入的图片文件类型如下 −
BMP | Windows Bitmap |
---|---|
GIF | Graphic Interchange Format (optional) |
JPG | Joint Photographic Experts Group |
JPEG | Joint Photographic Experts Group |
PNG | Portable Network Graphics |
PBM | Portable Bitmap |
PGM | Portable Graymap |
PPM | Portable Pixmap |
XBM | X11 Bitmap |
XPM | X11 Pixmap |
以下方法在处理 QPixmap 对象时很有用
序号 | 方法 & 说明 |
---|---|
1 | **copy()**从 QRect 对象复制像素图数据 |
2 | **fromImage()**将 QImage 对象转换为 QPixmap |
3 | **grabWidget()**从给定的小部件创建一个像素图 |
4 | **grabWindow()**在窗口中创建数据的像素图 |
5 | **Load()**将图像文件加载为像素图 |
6 | **save()**将 QPixmap 对象保存为文件 |
7 | toImage将 QPixmap 转换为 QImage |
QPixmap 最常见的用途是在标签/按钮上显示图像。
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *def window():app = QApplication(sys.argv)win = QWidget()l1 = QLabel()l1.setPixmap(QPixmap("python.png"))vbox = QVBoxLayout()vbox.addWidget(l1)win.setLayout(vbox)win.setWindowTitle("QPixmap Demo")win.show()sys.exit(app.exec_())if __name__ == '__main__':window()
运行结果: