【Python】PYQT5详细介绍

本专栏内容为: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 多个模块中定义。

以下是一些常用的模块 −

序号模块 & 说明
1QtCore其他模块使用的核心非 GUI 类
2QtGui图形用户界面组件
3QtMultimedia低级多媒体编程类
4QtNetwork网络编程类
5QtOpenGLOpenGL 支持类
6QtScript用于评估 Qt 脚本的类
7QtSql使用 SQL 进行数据库集成的类
8QtSvg显示 SVG 文件内容的类
9QtWebKit用于呈现和编辑 HTML 的类
10QtXml处理 XML 的类
11QtWidgets用于创建经典桌面样式 UI 的类。
12QtDesigner用于扩展 Qt Designer 的类
13QtAssistant支持在线帮助

PyQt5 开发工具是用于 Qt 开发的有用实用程序的集合。 以下是此类实用程序的精选列表 −

序号工具名称 & 说明
1assistantQt Assistant 文档工具
2pyqt5designerQt Designer GUI 布局工具
3linguistQt Linguist 翻译工具
4lrelease将ts文件编译成qm文件
5pylupdate5提取翻译字符串并生成或更新 ts 文件
6qmakeQt 软件构建工具
7pyqt5qmlsceneQML 文件查看器
8pyqmlviewerQML 文件查看器
9pyrcc5Qt资源文件编译器
10pyuic5用于从 ui 文件生成代码的 Qt 用户界面编译器
11pyqmltestrunner在 QML 代码上运行单元测试
12qdbus列出 D-Bus 服务的命令行工具
13QDocd软件项目的文档生成器。
14Qhelpgenerator生成和查看 Qt 帮助文件。
15qmlimportscanner解析和报告 QML 导入

PyQt API 包含 400 多个类。 QObject 类位于类层次结构的顶部。 它是所有 Qt 对象的基类。 此外,QPaintDevice 类是所有可绘制对象的基类。

QApplication 类管理 GUI 应用程序的主要设置和控制流程。 它包含主事件循环,在其中处理和调度由窗口元素和其他源生成的事件。 它还处理系统范围和应用程序范围的设置。

QWidget 类,派生自 QObject 和 QPaintDevice 类,是所有用户界面对象的基类。 QDialogQFrame 类也派生自 QWidget 类。 他们有自己的子类系统。

这里是常用小部件的选择列表

序号小部件和描述
1QLabel用于显示文本或图像
2QLineEdit允许用户输入一行文本
3QTextEdit允许用户输入多行文本
4QPushButton调用操作的命令按钮
5QRadioButton允许从多个选项中选择一个
6QCheckBox允许选择多个选项
7QSpinBox允许增加/减少整数值
8QScrollBar允许访问超出显示孔径的小部件的内容
9QSlider允许线性改变边界值。
10QComboBox提供可供选择的项目的下拉列表
11QMenuBar持有 QMenu 对象的水平条
12QStatusBar通常在 QMainWindow 的底部,提供状态信息。
13QToolBar通常在 QMainWindow 顶部或浮动。 包含操作按钮
14QListView在 ListMode 或 IconMode 中提供可选择的项目列表
15QPixmap显示在 QLabel 或 QPushButton 对象上的屏幕外图像表示
16QDialog****可以向父窗口返回信息的模态或非模态窗口

一个典型的基于 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.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))
        self.label.setText(_translate("MainWindow", "TextLabel"))


if __name__ == "__main__":
    import sys
    app = 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, QtWidgets


class 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: ignore
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "PushButton"))


if __name__ == "__main__":
    import sys
    app = 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 QtGui

def 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 实用程序一起使用的各种布局。

在这里插入图片描述

这是我们将在本章中一一讨论的类列表。

序号类 & 描述
1QBoxLayout QBoxLayout 类垂直或水平排列小部件。 它的派生类是 QVBoxLayout(用于垂直排列小部件)和 QHBoxLayout(用于水平排列小部件)。
2QGridLayout GridLayout 类对象呈现以行和列排列的单元格网格。 该类包含 addWidget() 方法。 通过指定单元格的行数和列数,可以添加任何小部件。
3QFormLayout 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 循环,由变量 ij 表示。它们被转换为字符串以连接要添加到 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 Class
   dlg.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 = 0

   def __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+1
         sub = 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.NoBrushNo brush pattern
Qt.SolidPatternUniform color
Qt.Dense1PatternExtremely dense brush pattern
Qt.HorPatternHorizontal lines
Qt.VerPatternVertical lines
Qt.CrossPatternCrossing horizontal and vertical lines
Qt.BDiagPatternBackward diagonal lines
Qt.FDiagPatternForward diagonal lines
Qt.DiagCrossPatternCrossing diagonal lines

预定义的 QColor 样式

下面给出的是预定义的 QColor 样式 −

Qt.NoBrushNo brush pattern
Qt.SolidPatternUniform color
Qt.Dense1PatternExtremely dense brush pattern
Qt.HorPatternHorizontal lines
Qt.VerPatternVertical lines
Qt.CrossPatternCrossing horizontal and vertical lines
Qt.BDiagPatternBackward diagonal lines
Qt.FDiagPatternForward diagonal lines
Qt.DiagCrossPatternCrossing 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对象可以读入的图片文件类型如下 −

BMPWindows Bitmap
GIFGraphic Interchange Format (optional)
JPGJoint Photographic Experts Group
JPEGJoint Photographic Experts Group
PNGPortable Network Graphics
PBMPortable Bitmap
PGMPortable Graymap
PPMPortable Pixmap
XBMX11 Bitmap
XPMX11 Pixmap

以下方法在处理 QPixmap 对象时很有用

序号方法 & 说明
1**copy()**从 QRect 对象复制像素图数据
2**fromImage()**将 QImage 对象转换为 QPixmap
3**grabWidget()**从给定的小部件创建一个像素图
4**grabWindow()**在窗口中创建数据的像素图
5**Load()**将图像文件加载为像素图
6**save()**将 QPixmap 对象保存为文件
7toImage将 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()

运行结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/616890.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vs2019 STL库里 判断函数类型的模板 is_function_v 与 is_const_v

(1)源代码如下: 经简单代码测试后,得出 vs2019 的 c 编译器 和 其 STL 库的观点与设计:is_const_v 用来判断类型 T 内是否含有 const 修饰符,含有 const 则返回真。但若 T 是含有 const 的引用类型&#xf…

实现红黑树

目录 红黑树的概念 红黑树的节点结构定义 红黑树的插入 红黑树的验证 实现红黑树完整代码 红黑树的概念 红黑树 ,是一种 二叉搜索树 ,但 在每个结点上增加一个存储位表示结点的颜色,可以是 Red 或 Black 。 通过对 任何一条从根到叶子的…

Dato for Mac v5.2.11激活版:掌握时间,掌控生活

在忙碌的生活中,您是否常常觉得时间不够用?Dato for Mac,您的时间管理专家,助您轻松掌控每一天。清晰的日历视图、个性化的提醒功能,让您的日程安排井井有条。无论是工作还是生活,Dato for Mac都能成为您的…

sqli-labs 第八关盲注python脚本

目录 ​编辑 判断库名 1.库名长度 2.库名 import requests import mathurl "http://127.0.0.1/Less-8"def dblength():for i in range(20):payload f"1 and length(database())>{i}-- "data {id: payload}res requests.get(url, paramsdata)if …

深入理解 Kolmogorov–Arnold Networks (KAN)

深入理解 Kolmogorov–Arnold Networks (KAN) 最近,一篇名为 KAN: Kolmogorov–Arnold Network 的论文在机器学习领域引起了广泛关注。这篇论文提出了一种全新的神经网络视角,并提出了一种可以替代现有多层感知器(MLP)的新方案。要…

超高频工业读写器的特点介绍及其适用场景!

超高频工业读写器根据设计方式不同,可分为一体式读写器和分体式读写器,不同读写器特点不同,适用场景也不同,下面我们就一起来了解一下超高频分体读写器适用场景有哪些。 超高频分体读写器介绍 超高频分体读写器是一种射频识别(R…

动态规划算法:⼦数组、⼦串系列(数组中连续的⼀段)

例题一 解法(动态规划): 算法思路: 1. 状态表⽰: 对于线性 dp ,我们可以⽤「经验 题⽬要求」来定义状态表⽰: i. 以某个位置为结尾,巴拉巴拉; ii. 以某个位置…

c++ map,set封装

map 是一个 kv 结构, set 是 k结构。 我们前面模拟实现了 红黑树,但是我们实现的红黑树把 kv 结构写死了,怎么样才能用泛型编程的思想来实现map和set呢 我们先简单看一下原码中是怎么实现的 1.原码实现逻辑 我们打开这里的 stl_set.h 通过…

Win10子系统wsl开机自启动jar包(nginx、redis、apache2、ssh等)

一. 需求背景 最近在研究nextcloud项目,选择了Win10子系统方案,而win10子系统wsl是通过接口实现的,很多linux上的常规操作在wsl上无法实现,比如配置开机自启动jar包以及其他依赖程序。只能通过windows系统重启时,自动执…

数据可视化训练第四天(模拟投掷筛子并且统计频次)

投掷一个筛子 import matplotlib.pyplot as plt from random import randint import numpy as npclass Die:"""模拟投掷筛子"""def __init__(self,num_sides6):self.num_sidesnum_sidesdef roll(self):return randint(1,self.num_sides)num1000…

day05-面向对象内存原理和数组

day05 面向对象内存原理和数组 我们在之前已经学习过创建对象了,那么在底层中他是如何运行的。 1.对象内存图 1.1 Java 内存分配 Java 程序在运行时,需要在内存中分配空间。为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域…

蓝桥杯-地宫取宝

X 国王有一个地宫宝库,是 nm 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签。 地宫的入口在左上角,出口在右下角。 小明被带到地宫的入口,国王要求他只能向右或向下行走。 走过某个格子时,如果那个…

睿尔曼机械臂ROS控制

下载git工程 git clone https://github.com/RealManRobot/rm_robot.git安装配置 catkin build rm_msgs source devel/setup.bash catkin build source setup.bash这里注意,如果采用setup.sh多半不会成功,必须要source setup.bash文件,ros才…

数据分析思维——数据埋点笔记,以电商为例

数据埋点 数据分析前提是有数据,数据从哪里来,要选择采集哪些数据都需要考虑。如某些app上的商品推荐,是基于哪些信息来预判的呢?因此作为数据分析师有必要系统的了解用户行为到用户数据的整个过程 何为数据埋点 每当用户在客户端…

JeeSite V5.7.0 发布,Java快速开发平台,Vite5、多项重构重磅升级

JeeSite V5.7.0 发布,Java快速开发平台,Vite5、多项重构重磅升级 升级内容 新增 参数配置 IP 地址黑白名单过滤器动态参数 新增 侧边栏是否展开第一个菜单的开关 first-open 新增 AesTypeHandler 处理字段数据加密解密或脱敏 新增 JsonTypeHandler …

FANUC机器人坐标系的分类和简介

1、概述 坐标系是为了确定机器人的位置和姿势而在机器人或空间上定义的位置指标系统,坐标系分为关节坐标系和直角坐标系,直角坐标系遵循右手定则,而关节坐标系则是以机器人每个轴所转动的角度来表示机器人当前的位置。 2、坐标系的分类及简…

2024 年最新本地、云服务器安装部署 miniconda 环境详细教程(更新中)

Anaconda 概述 Anaconda 是专门为了方便使用 Python 进行数据科学研究而建立的一组软件包,涵盖了数据科学领域常见的 Python 库,并且自带了专门用来解决软件环境依赖问题的 conda 包管理系统。主要是提供了包管理与环境管理的功能,可以很方便…

嵌入式全栈开发学习笔记---C语言笔试复习大全15

目录 指针运算 笔试题17 思考:*px、*px和(*px)的区别! 笔试题18 补充命令8:“cd ..”退回到上一级目录 补充命令9:“man 3 函数名”可以查看库函数的原型 const 修饰指针是什么意思?(笔试重点&#…

用hMailServer+roundcubemail+宝塔安装配置一个自己的邮箱服务

用hMailServerroundcubemail安装配置一个自己的邮箱服务 1、准备工具与资料: 云服务器一台 基础配置就行 2核4G。域名一个 以下用lizipro.cn示例。hMailServer安装包roundcubemail安装包异常处理插件补丁: libmysql.zip 2、hMailServer服务安装&#…