PyQt5新手教程(六万字)

打印 上一主题 下一主题

主题 844|帖子 844|积分 2532

PyQt界面开发的两种方式:可视化UI + 编程式UI

   

  • 可视化UI —— 适用于必要高度自定义或复杂交互的应用
    PyQt5 保姆级教程(从入门到醒目)
    PyQt5 小白从零开始(汇总篇)
    PyQt5 快速上手(基础知识)
    PyQt5 快速入门(bilibili视频教程)
  • 编程式UI —— 适用于界面相对简单或不必要频仍更改的项目
    详细先容了每个组件的属性,可以当作百科书学习一波
   

  • 可视化UI:基于 Qt Designer 的界面创建(可视化编辑工具:组件拖放、属性设置、布局管理等)   

    • 方式一:在 PyQt 应用程序中加载.ui 文件。
    • 方式二:将 .ui 文件转换为 .py 文件,从而直接在 Python 代码中使用。


     

  • .ui文件:仅包含界面计划的代码
  • .py文件:     

    • (编程式UI )包含界面计划 + 算法逻辑的代码
    • (在 .py 中调用 .ui )仅包含算法逻辑的代码

   

  • 编程式UI(手写UI):通过 Python 代码创建用户界面,不依赖可视化编辑工具。   

    • 优点:

      • 机动性与动态性:可以随时动态创建、修改或删除组件,满意特定需求。
      • 定制化:正确控制每个组件的属性、样式和行为,实现高度定制的界面计划。
      • 版本控制:界面定义生存在代码中,便于跟踪和管理变革。
      • 跨平台 :跨平台:使用 Python 创建的界面可在不同操作体系上运行,因 PyQt 支持跨平台特性。

    • 缺点:

      • 可读性差 : 对于不熟悉代码的人,布局和配置不易明白
      • 难以预览 :必要运行程序才气看到界面,而可视化编辑器可实时预览。
      • 时间消耗 :编写更多代码以定义布局、样式和复杂界面。


  从编程式 UI 切换到 Qt Designer 进行界面优化

   

  • 结合使用:可视化UI + 编程式UI   

    • (1)创建 .ui 文件:

      • 使用 Qt Designer 创建 .ui 文件
      • 根据必要添加并布局界面组件(按钮、标签、文本框等)。
      • 将与 main.py 文件中界面相关的代码(如信号连接、控件初始化等)转换为 UI 组件,通过拖放和属性设置来完成计划。

    • (2)编辑和生存 .ui 文件:

      • 在 Qt Designer 中编辑完成后,生存文件为 .ui 格式。该文件将包含界面计划的结构和属性,但不包罗任何算法逻辑。

    • (3).ui 文件转 .py 文件:

      • 在命令行中,使用 pyuic 工具将 .ui 文件转换为 .py 文件:pyuic5 -x your_ui_file.ui -o your_ui_file.py。该命令会生成一个 Python 文件(your_ui_file.py),此中包含界面计划的 Python 代码。

    • (4)整合代码:

      • 打开 main.py 文件,找到与算法逻辑相关的代码(比方数据处置惩罚、事件响应等)。
      • 将这些逻辑代码移植到刚生成的 your_ui_file.py 文件中,确保将逻辑与界面代码分开。
      • 在 main.py 中导入新的 UI 文件,并创建界面实例:from your_ui_file import Ui_MainWindow


  注意:仅在 .ui 文件中保留静态的界面计划,不包罗任何与界面相关的算法逻辑。如许可以确保 UI 的清晰和可维护性。
  一、PyQt 简介

PyQt官网首页:https://www.riverbankcomputing.com/software/pyqt/
通过 pip 安装 PyQt:pip install pyqt5
   PyQt定义
(1)是Python编程语言的一个GUI(图形用户界面)工具包,它允许开发职员使用Python语言创建桌面应用程序。PyQt提供了很多用于创建丰富多样的用户界面的类和功能,以及用于处置惩罚用户输入和交互的工具。
(2)是基于Qt库的Python封装,Qt是一个流行的C++框架,用于开发跨平台的应用程序。
    PyQt版本
提供了与Qt应用程序框架的Python绑定。每个版本的PyQt都是为不同的Qt版本而计划的。 目前PyQt只支持两个版本:
  

  • PyQt6:仅支持Python 3.6及更高版本,仅支持 Qt6 版本。(1)模块名称变更:在PyQt6中,模块名称进行了更改,以更好地与尺度Qt模块名称匹配。比方,QtWidgets模块在PyQt6中被称为QtWidgets,而不是PyQt5.QtWidgets。(2)新特性:PyQt6引入了一些新特性,改进了现有功能,以适应Qt6的变革。这包罗新的信号和槽语法等。(3)与PyQt5不同,PyQt6不再支持Qt4。
  • PyQt5:仅支持Python 2.7和Python 3.x,仅支持 Qt5 版本。但Python 2在2020年已不再得到官方支持。(广泛使用)PyQt5是最广泛使用的版本,很多应用程序和项目都在使用它。
  • PyQt4:重要支持Python 2.x,仅支持 Qt4 版本。只管它也有一个用于Python 3的版本,但相对较少使用。(已经过期)不再得到官方支持,因此不建议在新项目中使用它。
  二、PyQt 与 Qt 的蒙娜丽莎

   Qt 和 PyQt 是用于创建图形用户界面(GUI)的工具包,它们提供了丰富的类和功能,可以用于开发跨平台的桌面应用程序。
  

  •   Qt(跨平台的C++应用程序开发框架):
    (1)Qt是由挪威公司Trolltech(现在是Qt公司的一部门)开发。它最初是为相识决C++开发职员在不同平台上编写重复代码的问题而计划的。
    (2)支持多种操作体系(跨平台):Windows、macOS、Linux、iOS、Android等,因此可以实现跨平台的开发和摆设。
    (3) 用户交互和事件:Qt是一个面向对象的框架,使用信号和槽机制来处置惩罚用户交互和事件。
  •   PyQt(Qt的Python绑定,使用Python语言调用和使用Qt框架的功能):
    (1)PyQt由Riverbank Computing公司开发和维护。
    (2)支持多种操作体系(跨平台):由于PyQt是基于Qt的,并且可以在各种操作体系上运行。
    (3)用户交互和事件:PyQt使用Qt的信号和槽机制来处置惩罚用户交互和事件,同时也支持Python的语法和特性。
  备注:PyQt同时支持Qt Designer(图形界面计划器),开发者可以通过Qt Designer可视化计划界面,然后将其转换为Python代码。
    Qt 和 PyQt 的区别:
  

  • 编程语言:Qt是C++编写,而PyQt是Qt的Python编写。
  • 开发体验:PyQt相对于Qt更容易上手,Python代码通常比C++代码更简便和易读。
  • 性能差异:由于Qt是用C++编写的,其性能可能比PyQt轻微好一些。然而,对于大多数应用程序而言,性能差异并不显着,而开发服从更重要。
  • 应用范畴:由于Qt和PyQt都是用于GUI开发的,因此它们在各种应用范畴中都有广泛的应用,包罗桌面应用程序、嵌入式体系、游戏开发、数据可视化等。
  • 生态体系:Qt拥有广泛的C++社区和生态体系,可以找到更多的第三方库和资源。相比之下,PyQt稍逊一筹。
  三、PyQt 布局管理器(Layout Manager)

3.1、简介

3.1.1、布局管理器的定义

布局管理器(Layout Manager):用于在图形用户界面(GUI)中管理窗口中部件(Widget)布局的工具。通过容器的方式来部署和管理部件的位置和大小,而无需手动盘算和设置每个部件的位置(但支持)。
   

  • 自动布局:根据容器的大小和约束,自动分列和调整部件的位置和大小。如许,当窗口大小改变时,部件的布局也会自动调整,无需手动修改。
  • 支持多种类型:水平布局、垂直布局、网格布局等。
  • 支持容器嵌套:可以将多个布局管理器嵌套在一起,从而实现复杂的布局计划。
  • 可扩展性:布局管理器通常具有一定的可扩展性,允许开发者编写自定义的布局管理器,以满意特定的布局需求。
  • 与部件关联:布局管理器通常与部件相关联,开发者可以将部件添加到布局管理器中,并指定部件在布局中的位置和大小。
  • 事件处置惩罚:一些布局管理器还可以处置惩罚部件的事件,比方调整大小事件、重绘事件等,以便实现更高级的交互功能。
  • 跨平台性兼容性:布局管理器通常是跨平台的,可以在不同的操作体系上使用,并且能够保持同等的布局效果。
  3.1.2、布局管理器的类型

   

  • 盒子布局管理器 QBoxLayout:无法单独使用,其是QVBoxLayout和QHBoxLayout的基类,详细用法参考垂直和水平布局管理器。
  • 垂直布局管理器 QVBoxLayout:将部件 从上到下(垂直的) 分列在一列中。
  • 水平布局管理器 QHBoxLayout:将部件 从左到右(水平的) 分列在一行中。
  • 网格布局管理器 QGridLayout:将部件 指定位置(行 + 列) 分列在一个网格中。   

    • 如:在同一行中,指定多个部件的位置布局:[3 3 3] to [33 3] 表示将111格式变换为112格局。

  • 表单布局管理器 QFormLayout:对齐标签和输入框。常用于创建表单式的用户界面。
  • 堆叠布局管理器 QStackedLayout:管理多个窗口部件,但同一时间只能显示一个布局管理器,可以通过界面切换以显示不同的部件。如:选项卡界面。
  3.1.3、布局管理器的使用方法

(1)将部件添加到布局管理器中
(2)将布局管理器设置为窗口或部件(Widget)的重要布局(即可实现自动布局)
  1. """###################################
  2. (1)管理子部件
  3. (2)将子部件给到主部件
  4. (3)窗口显示主部件
  5. ###################################"""
  6. layout = QVBoxLayout()                                  # 创建一个垂直布局管理器对象(用于管理垂直排列的子部件)
  7. layout.addWidget(container_widget)          # 将名为container_widget的部件添加到垂直布局中
  8. central_widget = QWidget()                          # 创建一个QWidget对象(用作主窗口的中央部件)
  9. central_widget.setLayout(layout)                  # 将布局设置为central_widget的布局管理器,使布局成为central_widget的主要布局
  10. self.setCentralWidget(central_widget)          # 将central_widget设置为主窗口(通常是QMainWindow)的中央部件,以便显示在窗口中
复制代码
3.2、项目实战

3.2.0、添加伸缩项 layout.addStretch:控制组件之间的间距

   

  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QWidget, QSlider
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         VBox_layout = QVBoxLayout()
  7.         HBox_Layout = QHBoxLayout()
  8.         """(1)若在部件之前及之后分别添加伸缩项 ———— 组件居中"""
  9.         VBox_layout.addStretch(1)
  10.         slider = QSlider()
  11.         slider.setFixedHeight(500)
  12.         label1 = QLabel("Label 1")
  13.         label2 = QLabel("Label 2")
  14.         label3 = QLabel("Label 3")
  15.         """(2)若在部件之前添加伸缩项,部件跟在伸缩项的后面 ———— 组件置于底部"""
  16.         VBox_layout.addStretch(8)
  17.         HBox_Layout.addWidget(slider)
  18.         VBox_layout.addWidget(label1)
  19.         VBox_layout.addWidget(label2)
  20.         VBox_layout.addWidget(label3)
  21.         HBox_Layout.addLayout(VBox_layout)
  22.         """(3)若在部件之后添加伸缩项,部件被伸缩项顶在前面 ———— 组件置于顶部"""
  23.         VBox_layout.addStretch(1)
  24.         central_widget = QWidget()
  25.         central_widget.setLayout(HBox_Layout)
  26.         self.setCentralWidget(central_widget)
  27. if __name__ == "__main__":
  28.     app = QApplication(sys.argv)
  29.     window = MainWindow()
  30.     window.show()
  31.     sys.exit(app.exec_())
  32. """##########################################################################
  33. 函数简介:在布局中创建一个弹性空间,用于调整布局中各个部件的间距,以实现更好的分布和对齐效果。
  34. 函数说明:layout.addStretch()
  35. 输入参数:
  36.         伸缩项的权重为0(默认),这意味着它不会占用任何额外的空间。
  37.         伸缩项的权重为1(常用),将会根据权重在布局中占据一部分空间,从而将其他部件推向布局的边缘。
  38.         备注:若为其余数字,则权重值越大,伸缩空间越大。
  39. ##########################################################################"""
复制代码
3.2.1、垂直布局管理器 QVBoxLayout:按照从上到下的顺序分列组件


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         vbox = QVBoxLayout()
  7.         button1 = QPushButton("Button 1")
  8.         button2 = QPushButton("Button 2")
  9.         button3 = QPushButton("Button 3")
  10.         vbox.addWidget(button1)
  11.         vbox.addWidget(button2)
  12.         vbox.addWidget(button3)
  13.         central_widget = QWidget()
  14.         central_widget.setLayout(vbox)
  15.         self.setCentralWidget(central_widget)
  16. if __name__ == "__main__":
  17.     app = QApplication(sys.argv)
  18.     window = MainWindow()
  19.     window.show()
  20.     sys.exit(app.exec_())
复制代码
3.2.2、水平布局管理器 QHBoxLayout:按照从左到右的顺序分列组件


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, QPushButton
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         hbox = QHBoxLayout()
  7.         button1 = QPushButton("Button 1")
  8.         button2 = QPushButton("Button 2")
  9.         button3 = QPushButton("Button 3")
  10.         hbox.addWidget(button1)
  11.         hbox.addWidget(button2)
  12.         hbox.addWidget(button3)
  13.         central_widget = QWidget()
  14.         central_widget.setLayout(hbox)
  15.         self.setCentralWidget(central_widget)
  16. if __name__ == "__main__":
  17.     app = QApplication(sys.argv)
  18.     window = MainWindow()
  19.     window.show()
  20.     sys.exit(app.exec_())
复制代码
3.2.3、网格布局管理器 QGridLayout:指定每个组件的位置(行 + 列)


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout, QPushButton
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         grid_layout = QGridLayout()
  7.         button1 = QPushButton("Button 1")
  8.         button2 = QPushButton("Button 2")
  9.         button3 = QPushButton("Button 3")
  10.         button4 = QPushButton("Button 4")
  11.         button5 = QPushButton("Button 5")
  12.         grid_layout.addWidget(button1, 0, 0)        # 第一行第一列
  13.         grid_layout.addWidget(button2, 0, 1)        # 第一行第二列
  14.         grid_layout.addWidget(button3, 1, 0)        # 第二行第一列
  15.         grid_layout.addWidget(button4, 1, 1)        # 第二行第二列
  16.         grid_layout.addWidget(button5, 1, 2, 1, 2)  # 第二行的第三和第四列
  17.         central_widget = QWidget()
  18.         central_widget.setLayout(grid_layout)
  19.         self.setCentralWidget(central_widget)
  20. if __name__ == "__main__":
  21.     app = QApplication(sys.argv)
  22.     window = MainWindow()
  23.     window.show()
  24.     sys.exit(app.exec_())
复制代码
3.2.4、表单布局管理器 QFormLayout:对齐标签和输入框


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QFormLayout, QLineEdit, QLabel
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         form_layout = QFormLayout()
  7.         label1 = QLabel("Name:")
  8.         name_input = QLineEdit()
  9.         label2 = QLabel("Email:")
  10.         email_input = QLineEdit()
  11.         label3 = QLabel("Phone:")
  12.         phone_input = QLineEdit()
  13.         form_layout.addRow(label1, name_input)
  14.         form_layout.addRow(label2, email_input)
  15.         form_layout.addRow(label3, phone_input)
  16.         central_widget = QWidget()
  17.         central_widget.setLayout(form_layout)
  18.         self.setCentralWidget(central_widget)
  19. if __name__ == "__main__":
  20.     app = QApplication(sys.argv)
  21.     window = MainWindow()
  22.     window.show()
  23.     sys.exit(app.exec_())
复制代码
3.2.5、堆叠布局管理器 QStackedLayout:在一个窗口中,管理多个窗口,但同一时间只能显示一个窗口(如:选项卡界面)



  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QLabel, QVBoxLayout, QStackedLayout
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setWindowTitle("Stacked Layout Example")
  7.         
  8.         self.stacked_layout = QStackedLayout()
  9.         page1 = self.create_page("Page 1 Content", "Switch to Page 2")
  10.         page2 = self.create_page("Page 2 Content", "Switch to Page 1")
  11.         self.stacked_layout.addWidget(page1)
  12.         self.stacked_layout.addWidget(page2)
  13.         central_widget = QWidget()
  14.         central_widget.setLayout(self.stacked_layout)
  15.         self.setCentralWidget(central_widget)
  16.     def create_page(self, content_text, switch_button_text):
  17.         layout = QVBoxLayout()
  18.         content_label = QLabel(content_text)
  19.         switch_button = QPushButton(switch_button_text)
  20.         switch_button.clicked.connect(self.switch_page)
  21.         layout.addWidget(content_label)
  22.         layout.addWidget(switch_button)
  23.         page = QWidget()
  24.         page.setLayout(layout)
  25.         return page
  26.     def switch_page(self):
  27.         # 切换页面
  28.         current_index = self.stacked_layout.currentIndex()
  29.         next_index = (current_index + 1) % 2  # 切换到下一页(循环切换)
  30.         self.stacked_layout.setCurrentIndex(next_index)
  31. if __name__ == "__main__":
  32.     app = QApplication(sys.argv)
  33.     window = MainWindow()
  34.     window.show()
  35.     sys.exit(app.exec_())
复制代码
四、PyQt 常用组件

在 GUI 编程中,术语"组件"、"部件"和"控件"通常用于指代用户界面的根本构建块。术语在不同的 GUI 框架和文档中会略有不同,但可以互换使用。
4.1、简介

PyQt提供了丰富的组件(也称为控件或部件),用于构建图形用户界面。
组件(Widget)简介窗口组件QWidget全部用户界面对象的基类,用于创建窗口和部件。QMainWindow主窗口的类,通常用作应用程序的主界面。基础组件QLabel显示文本或图像。QLineEdit输入单行文本。QTextEdit输入多行文本。QSpinBox(数字)整数输入框。QDoubleSpinBox(数字)浮点数输入框。QPushButton按钮。QRadioButton单选按钮。在多个选项中进行单选。QCheckBox复选框。在多个选项中进行多选QGroupBox分组框。将其他小部件放置在此中QSlider滑动条。QTabWidget选项卡界面。QComboBox下拉列表框。对话框类 - 组件QDialog自定义对话框QInputDialog获取用户输入对话框QFontDialog字体对话框。QColorDialog颜色对话框。QProgressDialog进度对话框。QFileDialog打开文件/文件夹对话框。QMessageBox消息提示框。菜单类 - 组件QMenu菜单。QMenuBar菜单栏。QToolBar工具栏。QStatusBar状态栏。QProgressBar进度条。画图类 - 组件QGraphicsScene管理2D图形项的场景。QGraphicsView显示二维图形和图像。QGraphicsItem在QGraphicsScene中显示图形项。QTableView显示表格数据。QTreeWidget显示树形数据。QListWidget显示列表数据。QCalendarWidget显示日历。QDockWidget创建可停靠的面板。QSplitter在界面中创建可调整大小的分割区域。QScrollArea显示超过容器尺寸的内容,并支持滚动查察。 4.2、项目实战

4.2.0、不常用但实用的组件

  4.2.0.1、应用程序对象QApplication + 主窗口类QMainWindow + 全部用户界面对象的基类QWidget

QAction:用于表示用户界面中某个操作的类。它常与菜单、工具栏或按钮一起使用,以便用户实行特定的操作。
  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QPushButton, QLabel, QVBoxLayout
  3. class MyWindow(QMainWindow):
  4.     """自定义窗口类,继承自 QMainWindow"""
  5.     def __init__(self):
  6.         super().__init__()  # 调用父类 QMainWindow 的构造函数
  7.         self.initUI()  # 调用自定义初始化方法来设置窗口的 UI 元素
  8.     def initUI(self):
  9.         """初始化 UI 元素的方法"""
  10.         self.setWindowTitle("封装的 QWidget 示例")  # 设置窗口标题
  11.         self.setFixedSize(400, 300)  # 设置窗口大小
  12.         self.label = QLabel("这是一个标签", self)  # 创建按钮
  13.         self.button = QPushButton("点击我", self)  # 创建标签
  14.         self.button.clicked.connect(self.on_click)  # 将按钮点击事件与槽函数连接
  15.         # (1)自定义布局
  16.         layout = QVBoxLayout()  # 创建垂直布局
  17.         layout.addWidget(self.label)  # 将标签添加到布局
  18.         layout.addWidget(self.button)  # 将按钮添加到布局
  19.         # (2)将自定义布局设置为主窗口布局
  20.         widget = QWidget()  # 创建一个 QWidget 容器,用于承载其他部件和布局。
  21.         widget.setLayout(layout)  # 将 layout 布局设置为 QWidget 的布局
  22.         self.setCentralWidget(widget)  # 将 QWidget 设置为 QMainWindow 主窗口的中心部件,确保布局和控件显示在窗口中。
  23.     def on_click(self):
  24.         """按钮点击事件处理函数"""
  25.         self.label.setText("按钮被点击了!")
  26. if __name__ == '__main__':
  27.     app = QApplication(sys.argv)  # 创建一个 QApplication 应用程序对象,sys.argv 用于获取命令行参数。
  28.     """即使不需要处理参数,也必须传递此参数,以保持与操作系统兼容。"""
  29.     window = MyWindow()  # 实例化自定义窗口类
  30.     window.show()  # 显示创建的窗口
  31.     sys.exit(app.exec_())  # 进入应用程序的事件循环,等待用户交互,程序将在事件循环中持续运行,直到手动关闭。
  32.     # (1)app.exec_() 开始事件循环,等待用户事件(如点击、键盘输入等)。
  33.     # (2)sys.exit() 确保程序正常退出。
  34. """
  35. # QApplication 是一个应用程序对象,负责管理应用程序的控制流和主要设置。它是所有 GUI 应用程序的基础,必须在任何 GUI 元素创建之前初始化。
  36. # QMainWindow 是一个主窗口类,是一个特殊类型的 QWidget。支持添加菜单栏、工具栏、状态栏和中央小部件。它提供了一个结构化框架,适合复杂的应用程序开发。
  37. # QWidget 是所有用户界面对象的基类,几乎所有的部件都派生自 QWidget。可以作为一个容器,用于放置其他部件或布局。
  38. 在一个典型的 PyQt 应用程序中:
  39.         (1)QApplication 是首先创建的
  40.         (2)然后是 QMainWindow
  41.         (3)并且在 QMainWindow 中会使用 QWidget 作为中央小部件来承载其他控件。
  42. """
复制代码
  4.2.0.2、操作类QAction + 菜单栏QMenuBar +工具栏QToolBar + 状态栏QStatusBar

QAction:用于表示用户界面中某个操作的类。它常与菜单、工具栏或按钮一起使用,以便用户实行特定的操作。

  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QMenuBar, QToolBar, QStatusBar, QAction, QTextEdit, \
  3.     QFileDialog
  4. class MyWindow(QMainWindow):
  5.     def __init__(self):
  6.         super().__init__()
  7.         ###################################################
  8.         # (1)创建菜单栏,并添加一个菜单
  9.         menubar = self.menuBar()
  10.         file_menu = menubar.addMenu('File')
  11.         # (2)创建操作类,农添加到菜单栏
  12.         new_action = QAction('New', self)
  13.         open_action = QAction('Open', self)
  14.         save_action = QAction('Save', self)
  15.         exit_action = QAction('Exit', self)
  16.         file_menu.addAction(new_action)
  17.         file_menu.addAction(open_action)
  18.         file_menu.addAction(save_action)
  19.         file_menu.addSeparator()  # 分隔线
  20.         file_menu.addAction(exit_action)
  21.         # (3)连接菜单项和工具按钮的槽函数
  22.         new_action.triggered.connect(self.newFile)
  23.         open_action.triggered.connect(self.openFile)
  24.         save_action.triggered.connect(self.saveFile)
  25.         exit_action.triggered.connect(self.exitApp)
  26.         ###################################################
  27.         # (1)创建工具栏
  28.         toolbar = self.addToolBar('Toolbar')
  29.         # (2)在工具栏中,添加工具按钮
  30.         new_button = toolbar.addAction('New')  # 用于清空(当前)文本编辑框
  31.         open_button = toolbar.addAction('Open')  # 用于打开txt文本并添加到文本编辑框
  32.         save_button = toolbar.addAction('Save')  # 用于保存文本编辑框到txt文本
  33.         # (3)连接菜单项和工具按钮的槽函数
  34.         new_button.triggered.connect(self.newFile)
  35.         open_button.triggered.connect(self.openFile)
  36.         save_button.triggered.connect(self.saveFile)
  37.         ###################################################
  38.         # (1)创建状态栏
  39.         statusbar = self.statusBar()
  40.         # (2)在状态栏中显示消息: 'Ready' 是要显示的文本消息,3000 是消息显示的时间(以毫秒为单位),即3秒。
  41.         statusbar.showMessage('Ready', 3000)
  42.         ###################################################
  43.         # 创建文本编辑框
  44.         self.text_edit = QTextEdit(self)
  45.         self.setCentralWidget(self.text_edit)  # 将文本编辑框设置为主窗口的中心组件
  46.     def newFile(self):
  47.         self.text_edit.clear()  # 清空文本编辑框
  48.     def openFile(self):
  49.         try:
  50.             # 打开文件对话框 ———— 选择txt文件并读取内容,然后显示在文本编辑框中
  51.             file_dialog = QFileDialog(self)
  52.             file_path, _ = file_dialog.getOpenFileName()
  53.             if file_path:
  54.                 with open(file_path, 'r', encoding='utf-8') as file:
  55.                     file_contents = file.read()
  56.                     self.text_edit.setPlainText(file_contents)
  57.         except Exception as e:
  58.             print(f"Error opening file: {str(e)}")
  59.     def saveFile(self):
  60.         try:
  61.             # 保存文件对话框 ———— 将文本编辑框中的内容保存到txt文件中
  62.             file_dialog = QFileDialog(self)
  63.             file_path, _ = file_dialog.getSaveFileName()
  64.             if file_path:
  65.                 with open(file_path, 'w') as file:
  66.                     file_contents = self.text_edit.toPlainText()
  67.                     file.write(file_contents)
  68.         except Exception as e:
  69.             print(f"Error saving file: {str(e)}")
  70.     def exitApp(self):
  71.         self.close()
  72. if __name__ == '__main__':
  73.     app = QApplication(sys.argv)
  74.     window = MyWindow()
  75.     window.setWindowTitle('PyQt Text Editor')
  76.     window.setGeometry(100, 100, 800, 300)
  77.     window.show()
  78.     sys.exit(app.exec_())
复制代码
  4.2.0.3、【对话框类】输入对话框QInputDialog + 颜色对话框QColorDialog + 字体对话框QFontDialog + 文件选择对话框QFileDialog + 进度对话框QProgressDialog + 消息对话框QMessageBox

   

  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QInputDialog, QColorDialog, QFontDialog, QFileDialog, QProgressDialog, QMessageBox
  3. from PyQt5.QtCore import Qt
  4. from PyQt5.QtGui import QColor
  5. class MainWindow(QMainWindow):
  6.     def __init__(self):
  7.         super().__init__()
  8.         self.initUI()
  9.     def initUI(self):
  10.         self.setWindowTitle("Dialogs Example")
  11.         self.setGeometry(100, 100, 400, 300)
  12.         layout = QVBoxLayout()
  13.         # 显示输入对话框按钮
  14.         input_btn = QPushButton("Input Dialog")
  15.         input_btn.clicked.connect(self.show_input_dialog)
  16.         layout.addWidget(input_btn)
  17.         # 颜色对话框按钮
  18.         color_btn = QPushButton("Color Dialog")
  19.         color_btn.clicked.connect(self.show_color_dialog)
  20.         layout.addWidget(color_btn)
  21.         # 字体对话框按钮
  22.         font_btn = QPushButton("Font Dialog")
  23.         font_btn.clicked.connect(self.show_font_dialog)
  24.         layout.addWidget(font_btn)
  25.         # 打开文件对话框按钮
  26.         open_file_btn = QPushButton("Open File Dialog")
  27.         open_file_btn.clicked.connect(self.show_file_dialog)
  28.         layout.addWidget(open_file_btn)
  29.         # 进度对话框按钮
  30.         progress_btn = QPushButton("Progress Dialog")
  31.         progress_btn.clicked.connect(self.show_progress_dialog)
  32.         layout.addWidget(progress_btn)
  33.         # 消息框按钮
  34.         message_btn = QPushButton("Message Box")
  35.         message_btn.clicked.connect(self.show_message_box)
  36.         layout.addWidget(message_btn)
  37.         # 标签用于显示结果
  38.         self.result_label = QLabel()
  39.         layout.addWidget(self.result_label)
  40.         central_widget = QWidget()
  41.         central_widget.setLayout(layout)
  42.         self.setCentralWidget(central_widget)
  43.     def show_input_dialog(self):
  44.         text, ok = QInputDialog.getText(self, "Input Dialog", "Enter something:")
  45.         if ok and text:
  46.             self.result_label.setText(f"Input: {text}")
  47.         else:
  48.             self.result_label.setText("Input Dialog Canceled")
  49.     def show_color_dialog(self):
  50.         color = QColorDialog.getColor(QColor(255, 0, 0), self, "Color Dialog")
  51.         if color.isValid():
  52.             self.result_label.setStyleSheet(f"background-color: {color.name()}")
  53.             self.result_label.setText(f"Selected Color: {color.name()}")
  54.     def show_font_dialog(self):
  55.         font, ok = QFontDialog.getFont(self)
  56.         if ok:
  57.             self.result_label.setFont(font)
  58.             self.result_label.setText(f"Selected Font: {font.family()}, {font.pointSize()}pt")
  59.     def show_file_dialog(self):
  60.         file_name, _ = QFileDialog.getOpenFileName(self, "Open File Dialog", "", "All Files (*);;Text Files (*.txt)")
  61.         if file_name:
  62.             self.result_label.setText(f"Selected File: {file_name}")
  63.     def show_progress_dialog(self):
  64.         progress_dialog = QProgressDialog("Processing...", "Cancel", 0, 100, self)
  65.         progress_dialog.setWindowModality(Qt.WindowModal)
  66.         progress_dialog.setWindowTitle("Progress Dialog")
  67.         for i in range(100):
  68.             progress_dialog.setValue(i)
  69.             if progress_dialog.wasCanceled():
  70.                 break
  71.         self.result_label.setText("Progress Dialog Completed")
  72.     def show_message_box(self):
  73.         msg_box = QMessageBox()
  74.         msg_box.setIcon(QMessageBox.Information)
  75.         msg_box.setWindowTitle("Message Box")
  76.         msg_box.setText("This is an information message box.")
  77.         msg_box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
  78.         result = msg_box.exec_()
  79.         if result == QMessageBox.Ok:
  80.             self.result_label.setText("Message Box: Ok button clicked")
  81.         else:
  82.             self.result_label.setText("Message Box: Cancel button clicked")
  83. if __name__ == "__main__":
  84.     app = QApplication(sys.argv)
  85.     window = MainWindow()
  86.     window.show()
  87.     sys.exit(app.exec_())
复制代码
  4.2.0.4、分割线 QFrame


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QFrame, QVBoxLayout, QLabel, QWidget
  3. class FrameExample(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setWindowTitle("QFrame Example")
  7.         self.setGeometry(100, 100, 300, 200)
  8.         layout = QVBoxLayout()
  9.         label1 = QLabel("Above the frame")
  10.         layout.addWidget(label1)
  11.         frame = QFrame()
  12.         frame.setFrameShape(QFrame.HLine)  # 水平线
  13.         frame.setFrameShadow(QFrame.Sunken)  # 阴影效果
  14.         layout.addWidget(frame)
  15.         label2 = QLabel("Below the frame")
  16.         layout.addWidget(label2)
  17.         container = QWidget()
  18.         container.setLayout(layout)
  19.         self.setCentralWidget(container)
  20. if __name__ == "__main__":
  21.     app = QApplication(sys.argv)
  22.     window = FrameExample()
  23.     window.show()
  24.     sys.exit(app.exec_())
复制代码
  4.2.0.5、动态调整子部件大小 QSplitter


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QSplitter, QTextEdit, QWidget, QVBoxLayout
  3. class SplitterExample(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setWindowTitle("QSplitter Example")
  7.         self.setGeometry(100, 100, 400, 300)
  8.         splitter = QSplitter()
  9.         text_edit1 = QTextEdit("Text Edit 1")
  10.         text_edit2 = QTextEdit("Text Edit 2")
  11.         splitter.addWidget(text_edit1)
  12.         splitter.addWidget(text_edit2)
  13.         self.setCentralWidget(splitter)
  14. if __name__ == "__main__":
  15.     app = QApplication(sys.argv)
  16.     window = SplitterExample()
  17.     window.show()
  18.     sys.exit(app.exec_())
复制代码
  4.2.0.6、设置组件属性:尺寸 + 颜色 + 连接到槽(状态变革)

  1. self.setWindowTitle("Image Registration")          # 设置窗口标题
  2. self.setGeometry(100, 100, 800, 600)                  # 设置窗口初始大小(界面支持缩放)
  3. self.setFixedSize(1000, 650)                                  # 设置窗口固定大小(界面不支持缩放)
  4. # 设置按钮尺度
  5. button.setFixedSize(100, 35)          # 设置组件的尺寸
  6. button.setFixedWidth(35)                # 设置组件的宽度
  7. button.setFixedHeight(100)                # 设置组件的高度
  8. # 设置按钮颜色(背景 + 字体) ———— 可以分别设置
  9. button.setStyleSheet("background-color: green; color: white;")
  10. button.setChecked(True)          # 设置默认选择
  11. button.setEnabled(True)                # 是否启用按钮
  12. checkbox.isChecked()                # 判断按钮是否被选中
  13. # (状态变化)信号连接到槽
  14. self.checkbox.stateChanged.connect(self.function)   # 将(复选框)信号连接到槽
  15. self.slider.valueChanged.connect(self.function)     # 将(滑动条)信号连接到槽
  16. self.LineEdit.returnPressed.connect(self.function)  # 将(输入框)信号连接到槽
  17. self.button.clicked.connect(self.function)                  # 将(按钮)信号连接到槽
  18. self.text_edit.textChanged.connect(self.function)   # 将(输入框)信号连接到槽
复制代码
4.2.1、显示文本 QLabel:Hello, PyQt!


  1. from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout
  2. class MyApp(QWidget):
  3.     def __init__(self):
  4.         super().__init__()  # 调用父类的构造函数
  5.         # 创建垂直布局管理器
  6.         self.layout = QVBoxLayout()
  7.         # 创建标签对象并添加到布局中
  8.         self.label = QLabel('Hello, PyQt!')
  9.         self.layout.addWidget(self.label)
  10.         
  11.         self.setLayout(self.layout)  # 设置布局到当前窗口
  12.         self.show()  # 显示窗口
  13. if __name__ == '__main__':
  14.     import sys
  15.     app = QApplication(sys.argv)  # 创建应用程序对象
  16.     widget = MyApp()               # 创建窗口对象
  17.     sys.exit(app.exec_())          # 运行应用程序
复制代码
4.2.2、按钮 QPushButton:用户登录界面



  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout
  3. class LoginWindow(QWidget):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setWindowTitle("Login Window")
  7.         # 创建控件
  8.         self.username_label = QLabel("Username:")
  9.         self.username_edit = QLineEdit()
  10.         self.password_label = QLabel("Password:")
  11.         self.password_edit = QLineEdit()
  12.         self.login_button = QPushButton("Login")
  13.         self.login_button.clicked.connect(self.login)  # 连接按钮点击事件到槽函数
  14.         self.result_label = QLabel("")
  15.         # 将容器部件添加到主布局中
  16.         layout = QVBoxLayout()  # 垂直布局管理器
  17.         self.username_layout = QHBoxLayout()  # 水平布局管理器
  18.         self.username_layout.addWidget(self.username_label)  # 将文本框添加到水平布局管理器中
  19.         self.username_layout.addWidget(self.username_edit)  # 将按钮添加到水平布局管理器中
  20.         layout.addLayout(self.username_layout)  # layout.addLayout
  21.         self.password_layout = QHBoxLayout()  # 水平布局管理器
  22.         self.password_layout.addWidget(self.password_label)  # 将文本框添加到水平布局管理器中
  23.         self.password_layout.addWidget(self.password_edit)  # 将按钮添加到水平布局管理器中
  24.         layout.addLayout(self.password_layout)  # layout.addLayout
  25.         # 将登录按钮和结果标签添加到垂直布局中
  26.         layout.addWidget(self.login_button)  # layout.addWidget
  27.         layout.addWidget(self.result_label)  # layout.addWidget
  28.         # 设置窗口的主布局
  29.         self.setLayout(layout)
  30.     def login(self):
  31.         username = self.username_edit.text()
  32.         password = self.password_edit.text()
  33.         # 在这里可以编写登录验证逻辑,这里只是简单地判断用户名和密码是否为空
  34.         if username == 'you' and password == '66':
  35.             self.result_label.setText("Login successful!")
  36.         else:
  37.             self.result_label.setText("Please check username and password.")
  38. if __name__ == "__main__":
  39.     app = QApplication(sys.argv)
  40.     window = LoginWindow()
  41.     window.show()
  42.     sys.exit(app.exec_())
复制代码
4.2.3、文本框 QLineEdit + QTextEdit(单行 + 多行) —— 文本改变


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLabel, QLineEdit, QTextEdit
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         layout = QVBoxLayout()
  7.         # QLineEdit 示例
  8.         self.line_edit = QLineEdit(self)
  9.         self.line_edit.setPlaceholderText("Enter a number")
  10.         self.line_edit.textChanged.connect(self.show_line_edit_text)
  11.         # QTextEdit 示例
  12.         self.text_edit = QTextEdit(self)
  13.         self.text_edit.setPlaceholderText("Enter a number")
  14.         self.text_edit.textChanged.connect(self.show_text_edit_text)
  15.         layout.addWidget(QLabel("Single Line Input:"))
  16.         layout.addWidget(self.line_edit)
  17.         layout.addWidget(QLabel("Multi-line Text Input:"))
  18.         layout.addWidget(self.text_edit)
  19.         central_widget = QWidget()
  20.         central_widget.setLayout(layout)
  21.         self.setCentralWidget(central_widget)
  22.     def show_line_edit_text(self, text):
  23.         print("Line Edit Text:", text)
  24.     def show_text_edit_text(self):
  25.         text = self.text_edit.toPlainText()  # 获取 QTextEdit 的文本
  26.         print("Text Edit Text:", text)
  27. if __name__ == "__main__":
  28.     app = QApplication(sys.argv)
  29.     window = MainWindow()
  30.     window.show()
  31.     sys.exit(app.exec_())
复制代码
(1)输入框2将根据输入框1的值,自动盘算;
(2)若输入框2的值自定义,则自动盘算功能不启用。

  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit, QVBoxLayout, QWidget
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setWindowTitle("QLineEdit 信号示例")
  7.         self.line_edit_1 = QLineEdit(self)
  8.         self.line_edit_2 = QLineEdit(self)
  9.         self.is_programmatic_change = False
  10.         self.line_edit_1.textChanged.connect(self.on_text_changed)
  11.         self.line_edit_2.textChanged.connect(self.on_text_2_changed)
  12.         layout = QVBoxLayout()
  13.         layout.addWidget(self.line_edit_1)
  14.         layout.addWidget(self.line_edit_2)
  15.         container = QWidget()
  16.         container.setLayout(layout)
  17.         self.setCentralWidget(container)
  18.     def on_text_changed(self, text):
  19.         try:
  20.             value = int(text) + 1
  21.             self.is_programmatic_change = True
  22.             self.line_edit_2.setText(str(value))
  23.             self.is_programmatic_change = False
  24.         except ValueError:
  25.             # 如果转换失败(例如输入的不是数字),则清空第二个文本框
  26.             self.line_edit_2.clear()
  27.     def on_text_2_changed(self, text):
  28.         if self.is_programmatic_change:
  29.             self.line_edit_2.setStyleSheet("color: grey;")
  30.             print(f"输入框的值变化是由程序设置的,状态为{self.is_programmatic_change}")
  31.         else:
  32.             self.line_edit_2.setStyleSheet("color: black;")
  33.             print(f"输入框的值变化是由用户手动输入的,状态为{self.is_programmatic_change}")
  34. if __name__ == '__main__':
  35.     app = QApplication(sys.argv)
  36.     window = MainWindow()
  37.     window.show()
  38.     sys.exit(app.exec_())
复制代码
4.2.4、校验器 QRegExpValidator :用于限制用户在 QLineEdit 中输入的文本(英文 / 数字)


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLineEdit
  3. from PyQt5.QtCore import QRegExp
  4. from PyQt5.QtGui import QRegExpValidator
  5. class MainWindow(QMainWindow):
  6.     def __init__(self):
  7.         super().__init__()
  8.         layout = QVBoxLayout()
  9.         self.line_edit = QLineEdit(self)
  10.         self.line_edit.setPlaceholderText("Enter English and numbers only")
  11.         # english_only = QRegExp("[a-zA-Z]+")  # 创建一个正则表达式,用于匹配只包含英文字符的文本
  12.         # numbers_only = QRegExp("[0-9]+")  # 创建一个正则表达式,用于匹配只包含数字的文本
  13.         regex = QRegExp("[A-Za-z0-9]+")  # 创建一个正则表达式,只允许输入英文和数字
  14.         validator = QRegExpValidator(regex)
  15.         self.line_edit.setValidator(validator)
  16.         layout.addWidget(self.line_edit)
  17.         central_widget = QWidget()
  18.         central_widget.setLayout(layout)
  19.         self.setCentralWidget(central_widget)
  20. if __name__ == "__main__":
  21.     app = QApplication(sys.argv)
  22.     window = MainWindow()
  23.     window.show()
  24.     sys.exit(app.exec_())
  25. """##########################################################################
  26. 函数功能:QRegExp 类是 Qt 中用于处理正则表达式的类。
  27. 函数说明:QRegExp(pattern: str,
  28.                 caseSensitivity: Qt.CaseSensitivity = Qt.CaseSensitive,
  29.                 syntax: QRegExp.PatternSyntax = QRegExp.RegExp)
  30. 输入参数:
  31.         pattern             构造一个 QRegExp 对象,使用给定的正则表达式 pattern。
  32.         caseSensitivity     指定是否区分大小写,默认为区分大小写。
  33.         syntax              指定正则表达式的语法,默认为正则表达式语法。
  34. """
  35. """
  36. 函数功能:QRegExpValidator 类是 Qt 中用于输入验证的工具之一。它允许您使用正则表达式来限制用户在 QLineEdit 等控件中输入的文本。
  37. 函数说明:QRegExpValidator(regexp: QRegExp,
  38.                          parent: QObject = None)
  39. 输入参数:
  40.         regexp              构造一个 QRegExpValidator 对象,使用给定的正则表达式 regexp 进行验证。
  41.         parent              用于设置对象的父级。
  42. ##########################################################################"""
复制代码
4.2.5、校验器 QIntValidator + QDoubleValidator(整数 + 浮点数):用于限制用户在 QLineEdit 中输入的文本必须为数字。


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QLabel, QLineEdit
  3. from PyQt5.QtGui import QIntValidator, QDoubleValidator
  4. class MainWindow(QMainWindow):
  5.     def __init__(self):
  6.         super().__init__()
  7.         int_label = QLabel("Enter an int between [0, 100]:")
  8.         int_label.setFixedWidth(350)  # 设置固定的宽度
  9.         int_validator = QIntValidator(0, 100)       # 创建QIntValidator,设置范围:[0, 100]
  10.         int_lineedit = QLineEdit()                  # 创建一个 QLineEdit 控件
  11.         int_lineedit.setValidator(int_validator)    # 设置校验器
  12.         # 将校验器应用到QLineEdit控件中,用于限制用户只能输入 0 到 100 之间的整数。
  13.         double_label = QLabel("Enter an double between [0.0, 100.0]:")
  14.         double_label.setFixedWidth(350)  # 设置固定的宽度
  15.         double_validator = QDoubleValidator(0.0, 100.0, 2)       # 创建QDoubleValidator,设置范围:[0.0, 100.0],保留两位小数
  16.         double_lineedit = QLineEdit()                         # 创建一个 QLineEdit 控件
  17.         double_lineedit.setValidator(double_validator)           # 设置校验器
  18.         # 将校验器应用到QDoubleValidator控件中,用于限制用户只能输入 0.0 到 100.0 之间的浮点数。
  19.         # 布局管理器
  20.         V_layout = QVBoxLayout()
  21.         H1_layout = QHBoxLayout()
  22.         H2_layout = QHBoxLayout()
  23.         H1_layout.addWidget(int_label)
  24.         H1_layout.addWidget(int_lineedit)
  25.         H2_layout.addWidget(double_label)
  26.         H2_layout.addWidget(double_lineedit)
  27.         V_layout.addLayout(H1_layout)
  28.         V_layout.addLayout(H2_layout)
  29.         # 将布局应用于主窗口的中心区域
  30.         central_widget = QWidget()
  31.         central_widget.setLayout(V_layout)
  32.         self.setCentralWidget(central_widget)
  33. if __name__ == "__main__":
  34.     app = QApplication(sys.argv)
  35.     window = MainWindow()
  36.     window.show()
  37.     sys.exit(app.exec_())
  38. """##########################################################################
  39. from PyQt5.QtGui import QIntValidator
  40. 函数简介:在输入框中,限制用户输入的内容必须是符合一定范围的整数。
  41. 函数说明:QIntValidator(bottom, top, parent=None)
  42. 输入参数:
  43.         bottom:         校验的最小值。
  44.         top:            校验的最大值。
  45.         parent:         可选,父对象。
  46. 属性:   bottom():               获取校验的最小值。
  47.         top():                  获取校验的最大值。
  48. 方法:   setBottom(bottom):      设置校验的最小值。
  49.         setTop(top):            设置校验的最大值。
  50. ##########################################################################"""
  51. """##########################################################################
  52. from PyQt5.QtGui import QDoubleValidator
  53. 函数简介:在输入框中,限制用户输入的内容必须是符合一定范围的整数。
  54. 函数说明:QDoubleValidator(bottom, top, decimals, parent=None)
  55. 输入参数:
  56.         bottom:         浮点数的最小值,用户输入的浮点数不能小于该值。
  57.         top:            浮点数的最大值,用户输入的浮点数不能大于该值。
  58.         decimals:       小数位数,表示允许的小数点后的位数。
  59.         parent:         可选参数,父级 QObject。
  60. 方法:   bottom():                       返回校验器设置的最小值。
  61.         top():                          返回校验器设置的最大值。
  62.         decimals():                     返回校验器设置的小数位数。
  63.         setBottom(bottom: float):       设置校验器的最小值。
  64.         setTop(top: float):             设置校验器的最大值。
  65.         setDecimals(decimals: int):     设置校验器的小数位数。
  66. ##########################################################################"""
复制代码
4.2.6、输入框 QSpinBox + QDoubleSpinBox(整数 + 浮点数):支持上下按钮调治


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QWidget, QSpinBox, QDoubleSpinBox, QLabel
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         # 使用 QSpinBox 限制整数范围
  7.         QSpinBox_label = QLabel("int input:")
  8.         int_spinbox = QSpinBox()
  9.         int_spinbox.setRange(0, 100)  # 限制范围:[0, 100]
  10.         # 使用 QDoubleSpinBox 限制浮点数范围
  11.         QDoubleSpinBox_label = QLabel("double input:")
  12.         double_spinbox = QDoubleSpinBox()
  13.         double_spinbox.setRange(0.0, 100.0)          # 限制范围:[0.0, 100.0]
  14.         double_spinbox.setDecimals(2)                          # 保留2位小数
  15.         # 布局管理器
  16.         V_layout = QVBoxLayout()          # 垂直布局
  17.         H1_layout = QHBoxLayout()          # 水平布局
  18.         H2_layout = QHBoxLayout()          # 水平布局
  19.         
  20.         H1_layout.addWidget(QSpinBox_label)
  21.         H1_layout.addWidget(int_spinbox)
  22.         V_layout.addLayout(H1_layout)
  23.         H2_layout.addWidget(QDoubleSpinBox_label)
  24.         H2_layout.addWidget(double_spinbox)
  25.         V_layout.addLayout(H2_layout)
  26.         # 将布局应用于主窗口的中心区域
  27.         central_widget = QWidget()
  28.         central_widget.setLayout(V_layout)
  29.         self.setCentralWidget(central_widget)
  30. if __name__ == "__main__":
  31.     app = QApplication(sys.argv)
  32.     window = MainWindow()
  33.     window.show()
  34.     sys.exit(app.exec_())
复制代码
4.2.7、滑动条 QSlider:获取滑动条点击前后的值


  1. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QSlider, QLabel
  2. from PyQt5.QtCore import Qt
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         layout = QVBoxLayout()
  7.         self.slider = QSlider()
  8.         self.slider.setOrientation(Qt.Horizontal)
  9.         self.slider.setRange(0, 100)
  10.         layout.addWidget(self.slider)
  11.         self.label = QLabel("Previous Value: 0, Current Value: 0")
  12.         layout.addWidget(self.label)
  13.         self.previous_value = 0
  14.         self.slider.valueChanged.connect(self.slider_value_changed)
  15.         central_widget = QWidget()
  16.         central_widget.setLayout(layout)
  17.         self.setCentralWidget(central_widget)
  18.     def slider_value_changed(self, new_value):
  19.         self.label.setText(f"Previous Value: {self.previous_value}, Current Value: {new_value}")
  20.         self.previous_value = self.slider.value()  
  21.         # self.slider.value():获取的是点击slider之后的值,而不是当前slider显示的值
  22. if __name__ == "__main__":
  23.     app = QApplication([])
  24.     window = MainWindow()
  25.     window.show()
  26.     app.exec_()
复制代码
4.2.8、进度条 QProgressBar:创建一个进度条窗口(0~100%)


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar
  3. from PyQt5.QtCore import QTimer
  4. class MainWindow(QMainWindow):
  5.     def __init__(self):
  6.         super().__init__()
  7.         
  8.         # 设置窗口的几何属性
  9.         self.setGeometry(100, 100, 600, 200)
  10.         # 创建一个进度条并设置其几何属性
  11.         self.progress_bar = QProgressBar(self)
  12.         self.progress_bar.setGeometry(30, 40, 500, 25)
  13.         # 创建一个 "Start Progress" 按钮
  14.         start_button = QPushButton('Start Progress', self)
  15.         # 连接按钮的点击事件到 startProgress 函数
  16.         start_button.clicked.connect(self.startProgress)
  17.         # 设置按钮的固定宽度和位置
  18.         start_button.setFixedWidth(200)
  19.         start_button.move(30, 80)
  20.     def startProgress(self):
  21.         # 初始化进度为0
  22.         self.progress = 0
  23.         # 创建一个定时器
  24.         self.timer = QTimer(self)
  25.         # 连接定时器的超时事件到 updateProgress 函数
  26.         self.timer.timeout.connect(self.updateProgress)
  27.         # 每0.1秒触发一次定时器
  28.         self.timer.start(100)
  29.     def updateProgress(self):
  30.         # 增加进度
  31.         self.progress += 1
  32.         # 设置进度条的值
  33.         self.progress_bar.setValue(self.progress)
  34.         # 当进度达到100%时,停止定时器
  35.         if self.progress >= 100:
  36.             self.timer.stop()
  37. if __name__ == '__main__':
  38.     app = QApplication(sys.argv)
  39.     window = MainWindow()
  40.     window.show()
  41.     sys.exit(app.exec_())
复制代码
4.2.9、滚动条 QScrollArea:支持垂直和水平滚动

QScrollArea:用于处置惩罚内容超出可见区域时的滚动视图的一个组件。它允许用户在包含的区域内滚动内容,无论是单个小部件还是多个小部件的组合。常用于在显示长文本、图像库或复杂布局时。

  1. from PyQt5.QtWidgets import QApplication, QMainWindow, QScrollArea, QWidget, QVBoxLayout, QHBoxLayout, QLabel
  2. class MainWindow(QMainWindow):
  3.     def __init__(self):
  4.         super().__init__()
  5.         self.setWindowTitle("QScrollArea with Horizontal and Vertical")
  6.         self.setGeometry(100, 100, 400, 300)
  7.         # 创建一个 QScrollArea
  8.         scroll_area = QScrollArea(self)
  9.         scroll_area.setWidgetResizable(True)  # 设置内容自适应大小
  10.         ########################################################################
  11.         # 创建一个水平布局,包含多个标签
  12.         horizontal_layout = QHBoxLayout()
  13.         # 添加多个标签以增加内容的宽度
  14.         for i in range(20):
  15.             label = QLabel(f"Label {i+1}", self)
  16.             horizontal_layout.addWidget(label)
  17.         ########################################################################
  18.         # 创建一个 QWidget,作为滚动区域的内容
  19.         content_widget = QWidget()
  20.         content_layout = QVBoxLayout(content_widget)
  21.         # 将水平布局添加到内容布局
  22.         content_layout.addLayout(horizontal_layout)
  23.         # 添加额外的标签以增加内容的高度
  24.         for j in range(20):
  25.             label = QLabel(f"Vertical Label {j+1}", self)
  26.             content_layout.addWidget(label)
  27.         # 将内容小部件添加到 QScrollArea
  28.         scroll_area.setWidget(content_widget)
  29.         # 将 QScrollArea 设置为主窗口的中心小部件
  30.         self.setCentralWidget(scroll_area)
  31.         ########################################################################
  32. if __name__ == "__main__":
  33.     app = QApplication([])
  34.     window = MainWindow()
  35.     window.show()
  36.     app.exec_()
复制代码
4.2.10、下拉框 QComboBox:创建一个下拉框并添加选项


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLabel, QComboBox
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         label = QLabel("Select an option:")
  7.         combo_box = QComboBox()
  8.         combo_box.addItem("Option 1")
  9.         combo_box.addItem("Option 2")
  10.         combo_box.addItem("Option 3")
  11.         combo_box.currentIndexChanged.connect(self.selection_changed)  # 连接选项变更事件
  12.         self.result_label = QLabel("", self)
  13.         layout = QVBoxLayout()
  14.         layout.addWidget(combo_box)
  15.         layout.addWidget(label)
  16.         layout.addWidget(self.result_label)
  17.         central_widget = QWidget()
  18.         central_widget.setLayout(layout)
  19.         self.setCentralWidget(central_widget)
  20.     def selection_changed(self, index):
  21.         selected_option = self.sender().currentText()
  22.         self.result_label.setText(f"Selected: {selected_option}")
  23. if __name__ == "__main__":
  24.     app = QApplication(sys.argv)
  25.     window = MainWindow()
  26.     window.show()
  27.     sys.exit(app.exec_())
复制代码
4.2.11、复选框 QCheckBox:获取勾选状态


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QLabel, QCheckBox, QVBoxLayout, QWidget
  3. class CheckBoxExample(QWidget):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.initUI()
  7.     def initUI(self):
  8.         self.setWindowTitle('QCheckBox')
  9.         self.label = QLabel("")
  10.         self.checkBox = QCheckBox("Option")
  11.         layout = QVBoxLayout()
  12.         layout.addWidget(self.checkBox)
  13.         layout.addWidget(self.label)
  14.         self.setLayout(layout)
  15.         self.checkBox.clicked.connect(self.on_checkbox_clicked)
  16.     def on_checkbox_clicked(self):
  17.         if self.checkBox.isChecked():
  18.             self.label.setText("checkBox is checked")
  19.         else:
  20.             self.label.setText("checkBox is unchecked")
  21. if __name__ == '__main__':
  22.     app = QApplication(sys.argv)
  23.     window = CheckBoxExample()
  24.     window.show()
  25.     sys.exit(app.exec_())
复制代码
4.2.12、单选按钮 QRadioButton

 4.2.12.1、获取勾选状态


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QLabel, QRadioButton, QVBoxLayout, QWidget
  3. class RadioButtonExample(QWidget):
  4.     def __init__(self):
  5.         super().__init__()
  6.         
  7.         # 设置窗口标题
  8.         self.setWindowTitle('QRadioButton')
  9.         # 创建标签
  10.         self.label = QLabel("")
  11.         # 创建单选按钮
  12.         self.radioButton1 = QRadioButton("Option 1")
  13.         self.radioButton2 = QRadioButton("Option 2")
  14.         self.radioButton3 = QRadioButton("Option 3")
  15.         # 将单选按钮和标签添加到布局
  16.         layout = QVBoxLayout()
  17.         layout.addWidget(self.radioButton1)
  18.         layout.addWidget(self.radioButton2)
  19.         layout.addWidget(self.radioButton3)
  20.         layout.addWidget(self.label)
  21.         # 将布局设置为窗口的主布局
  22.         self.setLayout(layout)
  23.         # 连接单选按钮的点击事件到槽函数
  24.         self.radioButton1.clicked.connect(self.on_radio_button_clicked)
  25.         self.radioButton2.clicked.connect(self.on_radio_button_clicked)
  26.         self.radioButton3.clicked.connect(self.on_radio_button_clicked)
  27.     def on_radio_button_clicked(self):
  28.         sender = self.sender()  # 获取点击的单选按钮
  29.         self.label.setText("You selected: " + sender.text())  # 更新标签文本
  30. if __name__ == '__main__':
  31.     app = QApplication(sys.argv)
  32.     window = RadioButtonExample()
  33.     window.show()
  34.     sys.exit(app.exec_())
复制代码
 4.2.12.2、按钮分组 QButtonGroup:默认互斥

   

  • 步骤:使用 QButtonGroup 对多个 QRadioButton 分组,每个 QButtonGroup 可以包含多个 QRadioButton。
  • 备注:组内的按钮互斥,只有一个可以被选中,而不同组中的按钮是独立的。
  

  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QWidget, QRadioButton, QVBoxLayout, QButtonGroup, QFrame, QLabel
  3. class Window(QWidget):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setWindowTitle("QButtonGroup with Separator")
  7.         layout = QVBoxLayout()
  8.         # 第一组按钮
  9.         self.group1 = QButtonGroup(self)
  10.         group1_label = QLabel("Group 1:")
  11.         radio1_1 = QRadioButton("Group 1 - Option 1")
  12.         radio1_2 = QRadioButton("Group 1 - Option 2")
  13.         radio1_3 = QRadioButton("Group 1 - Option 3")
  14.         # 将按钮加入第一组
  15.         self.group1.addButton(radio1_1)
  16.         self.group1.addButton(radio1_2)
  17.         self.group1.addButton(radio1_3)
  18.         # 添加第一组到布局
  19.         layout.addWidget(group1_label)
  20.         layout.addWidget(radio1_1)
  21.         layout.addWidget(radio1_2)
  22.         layout.addWidget(radio1_3)
  23.         # 添加分隔线
  24.         line = QFrame()
  25.         line.setFrameShape(QFrame.HLine)
  26.         line.setFrameShadow(QFrame.Sunken)
  27.         layout.addWidget(line)
  28.         # 第二组按钮
  29.         self.group2 = QButtonGroup(self)
  30.         group2_label = QLabel("Group 2:")
  31.         radio2_1 = QRadioButton("Group 2 - Option 1")
  32.         radio2_2 = QRadioButton("Group 2 - Option 2")
  33.         # 将按钮加入第二组
  34.         self.group2.addButton(radio2_1)
  35.         self.group2.addButton(radio2_2)
  36.         # 添加第二组到布局
  37.         layout.addWidget(group2_label)
  38.         layout.addWidget(radio2_1)
  39.         layout.addWidget(radio2_2)
  40.         self.setLayout(layout)
  41. if __name__ == "__main__":
  42.     app = QApplication(sys.argv)
  43.     window = Window()
  44.     window.show()
  45.     sys.exit(app.exec_())
复制代码
4.2.13、分组框 QGroupBox:将其他小部件放置在此中


  1. from PyQt5.QtWidgets import QApplication, QGroupBox, QHBoxLayout, QRadioButton, QVBoxLayout, QWidget
  2. app = QApplication([])
  3. widget = QWidget()
  4. # 创建布局
  5. main_layout = QVBoxLayout()
  6. group_box = QGroupBox("Options")
  7. group_box_layout = QVBoxLayout()
  8. # 创建组件
  9. button1 = QRadioButton("Option 1")
  10. button2 = QRadioButton("Option 2")
  11. button3 = QRadioButton("Option 3")
  12. button4 = QRadioButton("Option 4")
  13. # 将组件添加到布局
  14. layout1 = QHBoxLayout()
  15. layout1.addWidget(button1)
  16. layout1.addWidget(button2)
  17. layout2 = QHBoxLayout()
  18. layout2.addWidget(button3)
  19. layout2.addWidget(button4)
  20. group_box_layout.addLayout(layout1)
  21. group_box_layout.addLayout(layout2)
  22. group_box.setLayout(group_box_layout)
  23. # 添加组件到主布局
  24. main_layout.addWidget(group_box)
  25. widget.setLayout(main_layout)
  26. widget.show()
  27. app.exec_()
复制代码
4.2.14、打印日志 QTextEdit:获取当前时间 + 设置文本颜色


  1. from PyQt5.QtWidgets import QApplication, QTextEdit, QVBoxLayout, QPushButton, QMainWindow, QWidget
  2. from PyQt5.QtCore import Qt, QDateTime
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.log_text_edit = QTextEdit()
  7.         self.button = QPushButton("Print Current Time")
  8.         self.button.clicked.connect(self.print_current_time)
  9.         
  10.         layout = QVBoxLayout()
  11.         layout.addWidget(self.log_text_edit)
  12.         layout.addWidget(self.button)
  13.         widget = QWidget()
  14.         widget.setLayout(layout)
  15.         self.setCentralWidget(widget)
  16.     def print_current_time(self):
  17.         current_time1 = QDateTime.currentDateTime().toString(Qt.DefaultLocaleLongDate)  # 指定默认格式
  18.         current_time2 = QDateTime.currentDateTime().toString("yyyy-M-d hh:mm:ss")  # 指定日期格式
  19.         message = current_time1 + r'<font color="red"> + {}</font>'.format(current_time2)
  20.         self.log_text_edit.append(message)
  21. if __name__ == '__main__':
  22.     app = QApplication([])
  23.     window = MainWindow()
  24.     window.show()
  25.     app.exec()
复制代码
  1. from datetime import datetime
  2. current_time = datetime.now()  # 获取当前时间
  3. formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
  4. print("Time:", formatted_time)  # 打印格式化后的时间
  5. # Time: 2023-08-08 14:25:29
复制代码
4.2.15、消息提示框 QMessageBox:信息 / 扣问 / 警告 / 错误

   

  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QMessageBox
  3. class MainWindow(QMainWindow):
  4.     def __init__(self):
  5.         super().__init__()
  6.         info_button = QPushButton("Information")
  7.         question_button = QPushButton("Question")
  8.         warning_button = QPushButton("Warning")
  9.         critical_button = QPushButton("Critical")
  10.         info_button.clicked.connect(self.show_information)
  11.         question_button.clicked.connect(self.show_question)
  12.         warning_button.clicked.connect(self.show_warning)
  13.         critical_button.clicked.connect(self.show_critical)
  14.         layout = QVBoxLayout()
  15.         layout.addWidget(info_button)
  16.         layout.addWidget(question_button)
  17.         layout.addWidget(warning_button)
  18.         layout.addWidget(critical_button)
  19.         widget = QWidget()
  20.         widget.setLayout(layout)
  21.         self.setCentralWidget(widget)
  22.     def show_information(self):
  23.         QMessageBox.information(self, "Information", "This is an information message.", QMessageBox.Ok, QMessageBox.Ok)
  24.     def show_question(self):
  25.         result = QMessageBox.question(self, "Question", "Do you want to proceed?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
  26.         if result == QMessageBox.Yes:
  27.             print("User clicked Yes")
  28.         else:
  29.             print("User clicked No")
  30.     def show_warning(self):
  31.         QMessageBox.warning(self, "Warning", "This is a warning message.", QMessageBox.Ok, QMessageBox.Ok)
  32.     def show_critical(self):
  33.         QMessageBox.critical(self, "Critical", "This is a critical message.", QMessageBox.Ok, QMessageBox.Ok)
  34. if __name__ == "__main__":
  35.     app = QApplication(sys.argv)
  36.     window = MainWindow()
  37.     window.show()
  38.     sys.exit(app.exec_())
  39. """##########################################################################
  40. from PyQt5.QtWidgets import QMessageBox
  41. 函数简介:用于显示消息框、询问框、警告框等用户交互提示框的类。
  42. 函数说明:
  43.         信息消息框        QMessageBox.information(parent, title, message, buttons, defaultButton)
  44.         询问消息框        QMessageBox.question(parent, title, message, buttons, defaultButton)
  45.         警告消息框        QMessageBox.warning(parent, title, message, buttons, defaultButton)
  46.         严重错误消息框     QMessageBox.critical(parent, title, message, buttons, defaultButton)
  47. 输入参数:
  48.         parent:         可选参数,父级窗口。
  49.         title:          消息框的标题。
  50.         message:        消息框中显示的消息文本。
  51.         buttons:        消息框中显示的按钮类型,如 QMessageBox.Yes、QMessageBox.No 等。
  52.         defaultButton:  可选参数,指定默认按钮。
  53. ##########################################################################"""
复制代码

  1. def show_warning(message=None):
  2.     import tkinter as tk
  3.     from tkinter import messagebox
  4.     root = tk.Tk()
  5.     root.withdraw()  # 隐藏主窗口
  6.     messagebox.showwarning("Warning", message)
  7.     root.destroy()  # 关闭主窗口
  8. if __name__ == '__main__':
  9.     show_warning(message="请仔细检查")
复制代码
4.2.16、选项卡界面 QTabWidget

 4.2.16.1、在一个窗口中显示多个页面

   Tab控件:可以在一个窗口中显示多个页面,每个页面对应一个选项卡,用户可以通过点击选项卡来切换不同的页面。

  1. from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QWidget, QVBoxLayout, QLabel
  2. class MyWindow(QMainWindow):
  3.     def __init__(self):
  4.         super().__init__()
  5.         # 创建Tab控件
  6.         self.tab_widget = QTabWidget()
  7.         self.setCentralWidget(self.tab_widget)
  8.         # 创建页面并添加到Tab控件中
  9.         self.page1 = QWidget()
  10.         self.page2 = QWidget()
  11.         self.tab_widget.addTab(self.page1, "Page 1")
  12.         self.tab_widget.addTab(self.page2, "Page 2")
  13.         # 设置页面的布局和内容
  14.         layout1 = QVBoxLayout()
  15.         layout1.addWidget(QLabel("This is Page 1"))
  16.         self.page1.setLayout(layout1)
  17.         layout2 = QVBoxLayout()
  18.         layout2.addWidget(QLabel("This is Page 2"))
  19.         self.page2.setLayout(layout2)
  20. if __name__ == "__main__":
  21.     app = QApplication([])
  22.     window = MyWindow()
  23.     window.show()
  24.     app.exec_()
复制代码
 4.2.16.2、在主界面中,显示其他.py界面类文件

   实现选项卡自动显示不同界面,可以在主界面的初始化过程中创建并添加不同的界面类实例,并根据选项卡的切换来显示相应的界面。

  1. # main.py
  2. import sys
  3. from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QWidget, QPushButton
  4. from other_file import OtherWindow  # 导入其他文件中的界面类
  5. class MainWindow(QMainWindow):
  6.     def __init__(self):
  7.         super().__init__()
  8.         self.setWindowTitle("Main Window")
  9.         self.setGeometry(200, 200, 300, 200)
  10.         # 创建一个QTabWidget控件
  11.         self.tab_widget = QTabWidget(self)
  12.         self.setCentralWidget(self.tab_widget)
  13.         # 创建页面1和页面2
  14.         self.page1 = QWidget()
  15.         self.page2 = OtherWindow()  # 调用其他文件中的界面类
  16.         # 将页面1和页面2添加到QTabWidget控件中
  17.         self.tab_widget.addTab(self.page1, "Page 1")
  18.         self.tab_widget.addTab(self.page2, "Page 2")
  19. if __name__ == "__main__":
  20.     app = QApplication(sys.argv)
  21.     main_window = MainWindow()
  22.     main_window.show()
  23.     sys.exit(app.exec_())
复制代码
  1. # other_file.py
  2. import sys
  3. from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QPushButton, QFileDialog
  4. class OtherWindow(QWidget):
  5.     def __init__(self):
  6.         super().__init__()
  7.         self.button = QPushButton("load:", self)
  8.         self.button.clicked.connect(self.load_image)
  9.         self.label = QLabel("")
  10.         button_layout = QHBoxLayout()
  11.         button_layout.addWidget(self.button)
  12.         button_layout.addWidget(self.label)
  13.         layout = QVBoxLayout()
  14.         layout.addLayout(button_layout)  # 将button_layout布局添加到主布局中
  15.         self.setLayout(layout)  # 设置窗口的主布局
  16.     def load_image(self):
  17.         self.folder_path = QFileDialog.getExistingDirectory(self, 'Select Folder', './')
  18.         if self.folder_path:
  19.             print('Selected Folder:', self.folder_path)
  20.             self.label.setText(self.folder_path)
  21. if __name__ == '__main__':
  22.     app = QApplication(sys.argv)
  23.     window = OtherWindow()
  24.     window.show()
  25.     sys.exit(app.exec_())
复制代码
 4.2.16.3、在主界面中,显示其他.py界面类文件,并进行数据交互

   

  1. # main.py
  2. import sys
  3. from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QWidget, QLineEdit, QPushButton, QHBoxLayout
  4. from other_file import OtherWindow
  5. class MainWindow(QMainWindow):
  6.     def __init__(self):
  7.         super().__init__()
  8.         self.setWindowTitle("Main Window")
  9.         self.setGeometry(200, 200, 300, 200)
  10.         self.send_button = QPushButton("Send Parameter", self)  # 新建按钮,并设置初始参数
  11.         self.send_button.clicked.connect(self.send_parameter)  # 使用connect方法将信号连接到槽
  12.         self.send_button.setStyleSheet("background-color: black; color: white;")  # 设置按钮的背景和字体颜色
  13.         self.input_line_edit = QLineEdit("Enter Parameter", self)  # 新建文本框,并设置初始参数
  14.         #####################################################################
  15.         # 创建一个QTabWidget控件
  16.         self.tab_widget = QTabWidget(self)
  17.         self.setCentralWidget(self.tab_widget)
  18.         # 创建页面1和页面2
  19.         self.page1 = QWidget()
  20.         self.other_window = OtherWindow()  # 调用其他文件中的界面类
  21.         # 将页面1和页面2添加到QTabWidget控件中
  22.         self.tab_widget.addTab(self.page1, "Page 1")
  23.         self.tab_widget.addTab(self.other_window, "Page 2")
  24.         #####################################################################
  25.         self.button_layout = QHBoxLayout()
  26.         self.button_layout.addWidget(self.send_button)
  27.         self.button_layout.addWidget(self.input_line_edit)
  28.         layout = QVBoxLayout()
  29.         layout.addLayout(self.button_layout)
  30.         layout.addWidget(self.tab_widget)
  31.         central_widget = QWidget()
  32.         central_widget.setLayout(layout)
  33.         self.setCentralWidget(central_widget)
  34.     def send_parameter(self):
  35.         parameter = self.input_line_edit.text()
  36.         self.other_window.receive_parameter(parameter)  # 调用其他界面类other_window中的函数receive_parameter
  37. if __name__ == "__main__":
  38.     app = QApplication(sys.argv)
  39.     window = MainWindow()
  40.     window.show()
  41.     sys.exit(app.exec_())
复制代码

  1. # other_file.py
  2. from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel
  3. import sys
  4. class OtherWindow(QWidget):
  5.     def __init__(self):
  6.         super().__init__()
  7.         button_layout = QHBoxLayout()  # 水平布局管理器
  8.         self.Received_button = QPushButton("Received Parameter", self)  # 新建按钮,并设置初始参数
  9.         self.Received_button.setStyleSheet("background-color: black; color: white;")  # 设置按钮的背景和字体颜色
  10.         self.label = QLabel("Hello from Other Window!")
  11.         button_layout.addWidget(self.Received_button)
  12.         button_layout.addWidget(self.label)
  13.         layout = QVBoxLayout()
  14.         layout.addLayout(button_layout)
  15.         self.setLayout(layout)
  16.     def receive_parameter(self, parameter):
  17.         self.label.setText(f"{parameter}")
  18. if __name__ == "__main__":
  19.     app = QApplication(sys.argv)
  20.     window = OtherWindow()
  21.     window.show()
  22.     sys.exit(app.exec_())
复制代码
 4.2.16.4、(主)选项卡 + (子)选项卡


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QTabWidget, QLabel
  3. class MainWindow(QWidget):
  4.     def __init__(self):
  5.         super().__init__()
  6.         # 设置窗口标题和初始大小
  7.         self.setWindowTitle("主Tab和子Tab示例")
  8.         self.setGeometry(100, 100, 800, 400)
  9.         # 创建主Tab控件
  10.         self.tab_widget = QTabWidget()
  11.         # 创建三个主Tab
  12.         self.tab1 = QWidget()
  13.         self.tab2 = QWidget()
  14.         self.tab3 = QWidget()
  15.         # 将主Tab添加到QTabWidget中
  16.         self.tab_widget.addTab(self.tab1, "主 Tab 1")
  17.         self.tab_widget.addTab(self.tab2, "主 Tab 2")
  18.         self.tab_widget.addTab(self.tab3, "主 Tab 3")
  19.         # 创建第一个主Tab中的子Tab
  20.         self.create_sub_tabs_for_tab1()
  21.         # 创建其他两个主Tab的内容
  22.         self.create_content_for_tab2()
  23.         self.create_content_for_tab3()
  24.         # 设置主布局
  25.         main_layout = QVBoxLayout()
  26.         main_layout.addWidget(self.tab_widget)
  27.         self.setLayout(main_layout)
  28.     def create_sub_tabs_for_tab1(self):
  29.         # 清空现有的所有内容
  30.         self.tab1_layout = QVBoxLayout()
  31.         self.tab1.setLayout(self.tab1_layout)
  32.         # 创建子Tab控件
  33.         self.sub_tab_widget = QTabWidget()
  34.         # 创建四个子Tab
  35.         for i in range(1, 5):
  36.             sub_tab = QWidget()
  37.             sub_tab_layout = QVBoxLayout()
  38.             sub_tab_layout.addWidget(QLabel(f"这是子 Tab {i} 的内容"))
  39.             sub_tab.setLayout(sub_tab_layout)
  40.             self.sub_tab_widget.addTab(sub_tab, f"子 Tab {i}")
  41.         # 将子Tab控件添加到主Tab中
  42.         self.tab1_layout.addWidget(self.sub_tab_widget)
  43.     def create_content_for_tab2(self):
  44.         layout = QVBoxLayout()
  45.         layout.addWidget(QLabel("这是主 Tab 2 的内容"))
  46.         self.tab2.setLayout(layout)
  47.     def create_content_for_tab3(self):
  48.         layout = QVBoxLayout()
  49.         layout.addWidget(QLabel("这是主 Tab 3 的内容"))
  50.         self.tab3.setLayout(layout)
  51. if __name__ == '__main__':
  52.     app = QApplication(sys.argv)
  53.     window = MainWindow()
  54.     window.show()
  55.     sys.exit(app.exec_())
复制代码
 4.2.16.5、左侧面板 + 选项卡


  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QTabWidget, QLabel
  3. class MainWindow(QWidget):
  4.     def __init__(self):
  5.         super().__init__()
  6.         # (1)设置窗口标题和初始大小
  7.         self.setWindowTitle("左侧面板和选项卡示例")
  8.         self.setGeometry(100, 100, 800, 400)
  9.         # (2)创建左侧按钮面板
  10.         self.left_panel = QVBoxLayout()
  11.         button1 = QPushButton("选项 1")  # 创建按钮
  12.         button2 = QPushButton("选项 2")  # 创建按钮
  13.         button3 = QPushButton("选项 3")  # 创建按钮
  14.         self.left_panel.addWidget(button1)  # 添加到左侧面板
  15.         self.left_panel.addWidget(button2)  # 添加到左侧面板
  16.         self.left_panel.addWidget(button3)  # 添加到左侧面板
  17.         self.left_panel.addStretch()  # 添加一个空白拉伸区域,以保证按钮在顶部排列
  18.         # (3)创建选项卡
  19.         self.tab_widget = QTabWidget()
  20.         # (4)创建主布局,将左侧面板和选项卡添加到水平布局中
  21.         main_layout = QHBoxLayout()
  22.         main_layout.addLayout(self.left_panel, 1)  # 左侧占1份空间
  23.         main_layout.addWidget(self.tab_widget, 4)  # 选项卡区域占4份空间
  24.         self.setLayout(main_layout)
  25.         # (5)初始界面将显示“选项 1”下的内容(默认不显示)
  26.         self.create_tabs_for_option1()
  27.         # (6)将按钮点击事件连接到相应的槽函数
  28.         button1.clicked.connect(self.create_tabs_for_option1)  # 连接按钮点击事件
  29.         button2.clicked.connect(self.create_content_for_option2)  # 连接按钮点击事件
  30.         button3.clicked.connect(self.create_content_for_option3)  # 连接按钮点击事件
  31.     def create_tabs_for_option1(self):
  32.         self.tab_widget.clear()  # 清空现有的所有 Tabs
  33.         self.tab_widget.tabBar().setVisible(True)  # 显示Tab标签栏
  34.         # 创建 4 个子 Tab
  35.         self.tab1 = QWidget()
  36.         self.tab2 = QWidget()
  37.         self.tab3 = QWidget()
  38.         self.tab4 = QWidget()
  39.         # 将子 Tab 添加到 QTabWidget 中
  40.         self.tab_widget.addTab(self.tab1, "Tab 1")
  41.         self.tab_widget.addTab(self.tab2, "Tab 2")
  42.         self.tab_widget.addTab(self.tab3, "Tab 3")
  43.         self.tab_widget.addTab(self.tab4, "Tab 4")
  44.         # 设置每个 Tab 的布局和内容
  45.         self.tab1_layout = QVBoxLayout()
  46.         self.tab1_layout.addWidget(QLabel("这是 Tab 1 的内容"))
  47.         self.tab1.setLayout(self.tab1_layout)
  48.         self.tab2_layout = QVBoxLayout()
  49.         self.tab2_layout.addWidget(QLabel("这是 Tab 2 的内容"))
  50.         self.tab2.setLayout(self.tab2_layout)
  51.         self.tab3_layout = QVBoxLayout()
  52.         self.tab3_layout.addWidget(QLabel("这是 Tab 3 的内容"))
  53.         self.tab3.setLayout(self.tab3_layout)
  54.         self.tab4_layout = QVBoxLayout()
  55.         self.tab4_layout.addWidget(QLabel("这是 Tab 4 的内容"))
  56.         self.tab4.setLayout(self.tab4_layout)
  57.     def create_content_for_option2(self):
  58.         self.tab_widget.clear()  # 清空现有的所有 Tabs
  59.         self.tab_widget.tabBar().setVisible(False)  # 隐藏Tab标签栏
  60.         # 创建一个 Tab,显示单一界面内容
  61.         single_tab = QWidget()  # 创建一个 QWidget 对象作为单个页面的容器
  62.         layout = QVBoxLayout()  # 创建一个 QVBoxLayout 布局对象,用于垂直排列控件
  63.         layout.addWidget(QLabel("这是选项 2 的内容"))  # 创建一个 QLabel 对象
  64.         single_tab.setLayout(layout)  # 将布局设置为 single_tab 的主布局
  65.         self.tab_widget.addTab(single_tab, "选项 2")  # 将页面添加到 QTabWidget 中
  66.     def create_content_for_option3(self):
  67.         self.tab_widget.clear()  # 清空现有的所有 Tabs
  68.         self.tab_widget.tabBar().setVisible(False)  # 隐藏Tab标签栏
  69.         # 创建一个 Tab,显示单一界面内容
  70.         single_tab = QWidget()  # 创建一个 QWidget 对象作为单个页面的容器
  71.         layout = QVBoxLayout()  # 创建一个 QVBoxLayout 布局对象,用于垂直排列控件
  72.         layout.addWidget(QLabel("这是选项 3 的内容"))  # 创建一个 QLabel 对象
  73.         single_tab.setLayout(layout)  # 将布局设置为 single_tab 的主布局
  74.         self.tab_widget.addTab(single_tab, "选项 3")  # 将页面添加到 QTabWidget 中
  75. if __name__ == '__main__':
  76.     app = QApplication(sys.argv)
  77.     window = MainWindow()
  78.     window.show()
  79.     sys.exit(app.exec_())
复制代码
4.3、别的功能

4.3.1、调用其他.py文件,并数据交互

   共有两种方法:
  

  • (1)QProcess(process.start):必要依赖Qt库。实现与外部应用程序的交互、启动和管理等功能,更加机动。适用于更复杂的交互和历程管理。
  • (2)subprocess(subprocess.run):Python尺度库提供的方法,更加简单方便。适用于在Python脚本中实行外部命令或脚本,并获取其结果。
  测试文件.py

  1. # other_file.py
  2. # 在这里进行运算或其他处理
  3. result = 42
  4. # 将结果打印到控制台
  5. print(result)
  6. print("result =", result + 1)
  7. print("result" + " + " + "result")
复制代码
方法一:subprocess(subprocess.run)

   

  1. # main.py
  2. import sys
  3. import subprocess
  4. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel
  5. class MainWindow(QMainWindow):
  6.     def __init__(self):
  7.         super().__init__()
  8.         self.run_button = QPushButton("run .py")
  9.         self.run_button.clicked.connect(self.run)
  10.         self.run_label = QLabel("", self)
  11.         layout = QVBoxLayout()
  12.         layout.addWidget(self.run_button)
  13.         layout.addWidget(self.run_label)
  14.         central_widget = QWidget()
  15.         central_widget.setLayout(layout)
  16.         self.setCentralWidget(central_widget)
  17.     def run(self):
  18.         try:
  19.                 #########################################################
  20.                 # 若不确定other_file.py是否调用成功,可以使用绝对路径。
  21.             # 不建议:调用.py文件
  22.             # 建议:将py文件封装成一个函数,然后调用函数。
  23.                 #########################################################
  24.             result = subprocess.run(["python", "other_file.py"], capture_output=True, text=True, check=True)
  25.             output = result.stdout.strip()  # 获取输出结果并去除首尾空格
  26.             self.run_label.setText(output)
  27.         except subprocess.CalledProcessError as e:
  28.             self.run_label.setText(str(e))
  29. if __name__ == "__main__":
  30.     app = QApplication(sys.argv)
  31.     window = MainWindow()
  32.     window.show()
  33.     sys.exit(app.exec_())
  34. """##########################################################################
  35. import subprocess
  36. 函数简介:Python标准库subprocess模块中的一个函数,用于运行一个子进程并等待其完成。
  37.                  可以执行系统命令或其他可执行文件,并可以通过参数来控制进程的行为和交互。
  38. 函数说明:subprocess.run(args, *, stdin=None, input=None, stdout=None,
  39.                                                  stderr=None, shell=False, cwd=None, timeout=None,
  40.                                                  check=False, encoding=None, errors=None, text=None,
  41.                                                  env=None, universal_newlines=None, start_new_session=False)
  42. 输入参数:
  43.                 args: 要运行的命令或可执行文件,以列表或字符串形式传递。如果shell=True,可以传递一个字符串,使用Shell运行命令。
  44.                 stdin: 用于传递子进程的标准输入的文件对象。
  45.                 input: 用于传递子进程的标准输入的字节或字符串数据。
  46.                 stdout: 用于接收子进程的标准输出的文件对象。
  47.                 stderr: 用于接收子进程的标准错误输出的文件对象。
  48.                 shell: 是否在Shell中运行命令。如果为True,可以使用通配符等Shell特性。
  49.                 cwd: 子进程的当前工作目录。
  50.                 timeout: 等待子进程完成的超时时间,如果子进程在此时间内未完成,将会被终止。
  51.                 check: 是否检查返回代码。如果为True,如果子进程返回的代码非零,将会引发CalledProcessError异常。
  52.                 encoding: 用于解码子进程输出的编码。
  53.                 errors: 用于处理解码错误的策略。
  54.                 text: 是否使用文本模式传递数据,相当于同时设置universal_newlines和encoding。
  55.                 env: 用于指定子进程的环境变量。
  56.                 universal_newlines: 是否使用通用换行符模式,相当于同时设置stdin、stdout和stderr的text参数。
  57.                 start_new_session: 是否在新的会话(session)中启动子进程。
  58. 输出参数:
  59.                 返回一个CompletedProcess对象,它包含有关子进程执行的信息,如返回代码、标准输出、标准错误等。
  60. ##########################################################################"""
复制代码
方法二:QProcess(process.start)

   

  1. # main.py
  2. import sys
  3. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel
  4. from PyQt5.QtCore import QProcess
  5. class MainWindow(QMainWindow):
  6.     def __init__(self):
  7.         super().__init__()
  8.         self.run_button = QPushButton("run .py")
  9.         self.run_button.clicked.connect(self.run)
  10.         self.run_label = QLabel("", self)
  11.         
  12.         layout = QVBoxLayout()
  13.         layout.addWidget(self.run_button)
  14.         layout.addWidget(self.run_label)
  15.         central_widget = QWidget()
  16.         central_widget.setLayout(layout)
  17.         self.setCentralWidget(central_widget)
  18.     def run(self):
  19.         # 清空结果标签
  20.         self.run_label.setText("")
  21.         #########################################################
  22.         # (1)启动进程执行外部脚本
  23.         process = QProcess()
  24.         python_script = r'other_file.py'  # 注意:若不确定other_file.py是否调用成功,可以使用绝对路径。
  25.         para1 = str(9)  # (1)传递参数只能是字符串(2)与外部脚本完成交互。
  26.         process.start("python", [python_script, para1])
  27.         process.waitForFinished(-1)  # 用于等待进程执行完成。传入参数-1表示无限等待
  28.         # (2)进程的退出代码:(1)0表示进程成功执行完成;(2)非零值表示出现错误。
  29.         exit_code = process.exitCode()
  30.         if exit_code == 0:
  31.             self.run_label.setText("调用【成功】,退出代码:{}".format(exit_code))
  32.         else:
  33.             self.run_label.setText("调用【失败】,退出代码:{}".format(exit_code))
  34. if __name__ == "__main__":
  35.     app = QApplication(sys.argv)
  36.     window = MainWindow()
  37.     window.show()
  38.     sys.exit(app.exec_())
  39. """######################################################################################
  40. # 函数介绍:QProcess 是 Qt 框架中用于创建和管理外部进程的类。它允许你启动外部应用程序,并与其进行通信。
  41. # 常见方法:
  42. #       (1)启动外部进程:         使用start()方法启动一个外部进程
  43. #       (2)与进程通信:           使用write()方法向进程的标准输入写入数据,并使用readAllStandardOutput()和readAllStandardError()方法读取进程的标准输出和标准错误输出。
  44. #       (2)等待进程执行完成:     使用waitForFinished()方法来等待进程执行完成
  45. #       (3)获取进程退出代码:     使用exitCode()方法可以获取进程的退出代码
  46. #       (4)支持信号与槽机制:     使用readyReadStandardOutput()信号在进程有标准输出可读时发出
  47. #       (5)中断进程:            使用terminate()方法尝试终止进程的执行。不一定会立即停止进程,具体行为取决于操作系统和进程本身。
  48. #
  49. #               process = QProcess()
  50. #               process.start("python", ["script.py", "arg1", "arg2"])
  51. #               if process.waitForFinished():
  52. #                   print("Process finished")
  53. #               exit_code = process.exitCode()
  54. #               if exit_code == 0:
  55. #                   print("调用成功")
  56. #               else:
  57. #                   print("调用失败,退出代码:", exit_code)
  58. #
  59. #               process.write(b"input data")
  60. #               output = process.readAllStandardOutput()
  61. #               error_output = process.readAllStandardError()
  62. #               process.readyReadStandardOutput.connect(handle_output)
  63. #               process.terminate()
  64. ######################################################################################"""
  65. """######################################################################################
  66. # 函数介绍:waitForFinished 是 QProcess 类的一个成员函数。用于阻塞当前线程,直到关联的进程完成执行为止。
  67. # 函数说明:bool QProcess.waitForFinished(int msecs = 30000)
  68. # 输入参数:     msecs:等待的时间(以毫秒为单位)。默认值是 30000 毫秒(30 秒)。如果设置为 -1,表示无限等待。
  69. # 输出参数:     如果进程在给定的时间内完成执行,则返回 True,否则返回 False。
  70. #
  71. # (1)主要用于等待 QProcess 执行外部程序的过程完成。程序会阻塞当前线程,阻塞在当前行,直到被调用的进程执行完毕。
  72. # (2)如果进程执行的时间很长,这会导致界面冻结,因为界面线程会被阻塞。
  73. # (3)如果你需要在界面上显示进度或状态,或者想要允许用户继续操作界面,而不阻塞界面线程,可以考虑使用多线程、异步编程等技术,以避免界面的冻结。
  74. ######################################################################################"""
复制代码
4.3.2、在当前虚拟情况下,调用其他虚拟情况下的.py文件,并数据交互

  1. import subprocess
  2. import os
  3. virtual_env_name = "tensorflow36"                               # (1)指定要激活的虚拟环境名称
  4. cmd_activate_env = f"conda activate {virtual_env_name}"         # (2)构建激活虚拟环境的命令
  5. script_path = r"deeplearning.py"                                # (3)指定.py文件路径
  6. path = os.getcwd() + 'image.tif'                                # (4)指定.py文件参数
  7. cmd_script_file = f"python {script_path} --image_path {path}"   # (5)构建调用.py文件的命令,包括传递参数
  8. # (6)使用subprocess执行命令
  9. ###################################################################################
  10. # 在Windows上,通过subprocess.run来激活一个Conda环境并不是一种有效的方式。
  11. #       原因分析:因为conda activate命令会在一个新的子进程中执行,该子进程的环境变量变化不会影响到当前Python进程中运行的后续代码。
  12. #       解决方法:将激活环境和执行py文件的命令,同时传递给subprocess.run。
  13. ###################################################################################
  14. combined_cmd = f"{cmd_activate_env} && {cmd_script_file}"       # 组合两个命令并在子进程中执行
  15. try:
  16.     subprocess.run(combined_cmd, shell=True, check=True)
  17. except subprocess.CalledProcessError as e:
  18.     print(f"Error: {e}")
  19. """######################################################################
  20. import argparse                             # 导入argparse模块
  21. if __name__ == "__main__":
  22.     parser = argparse.ArgumentParser()      # 创建解析对象
  23.     parser.add_argument('--image_path')     # 添加命令行参数和选项
  24.     args = parser.parse_args()              # 解析添加的参数
  25.     image_path = args.image_path            # 获取添加的参数
  26. ######################################################################"""
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

忿忿的泥巴坨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表