Python 小白从零开始 PyQt5 项目实战折叠侧边栏的实现

Posted youcans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 小白从零开始 PyQt5 项目实战折叠侧边栏的实现相关的知识,希望对你有一定的参考价值。

单式状态栏,位于于窗口的左右侧边,可以实现软件功能或目录的导航。
本文详细介绍用 QTreeWidget 部件实现目录结构的折叠侧边栏,与用 QToolBox 部件实现垂直菜单结构的折叠侧边栏,通过案例带小白建立两种典型的折叠侧边栏。
至此,我们已经完成了一个比较完整的应用程序的 UI 和程序框架。

欢迎关注『Python 小白从零开始 PyQt5 项目实战 @ Youcans』系列,持续更新中
Python 小白从零开始 PyQt5 项目实战(1)安装与环境配置
Python 小白从零开始 PyQt5 项目实战(2)菜单和工具栏
Python 小白从零开始 PyQt5 项目实战(3)信号与槽的连接
Python 小白从零开始 PyQt5 项目实战(4)基本控件
Python 小白从零开始 PyQt5 项目实战(5)布局管理
Python 小白从零开始 PyQt5 项目实战(6)窗口切换的堆叠布局
Python 小白从零开始 PyQt5 项目实战(7)折叠侧边栏的实现



1. 折叠侧边栏

1.1 什么是折叠侧边栏

布局管理就是管理图形窗口中各个部件的位置和排列。前文中我们不仅介绍了基本的水平布局、垂直布局、栅格布局、表格布局和进阶的嵌套布局和容器布局,而且着重介绍了通过堆叠布局实现多个不同图形页面面的切换,以适应不同的任务场景。

折叠侧边栏在实际项目中也非常实用,可以实现软件功能或目录的导航。

折叠侧边栏,是指可折叠的多级菜单式状态栏,位于于窗口的左右侧边。

折叠侧边栏也称为垂直多级菜单,因此其外观、功能与操作与菜单栏基本相似。

折叠侧边栏通常只展开第一级目录(根目录)的内容,可以显示文本、图标和按键,点击上一级目录可以展开或折叠下一级的目录。点击最底层目录可以完成指定的操作,如执行所连接的槽函数。

折叠侧边栏的形式多样,如网站导航、资源管理器的目录形式,或手风琴形式、滑动菜单形式、按键列表形式。


1.2 折叠侧边栏的实现方案

折叠侧边栏的形式多样,如浏览器、资源管理器的目录形式,或多级菜单形式,或按键列表形式。

QtDesigner 提供了多种部件,可以实现不同形式的折叠侧边栏。

树结构部件 Tree View 和 Tree Widget 可以建立目录树结构的侧边栏,二者分别基于模型(Model)和项目(Item), Tree Widget 是 Tree View 的子类。

抽屉结构部件 ToolBox 是一种容器布局控件,可以建立菜单形式或按键列表形式的侧边栏。



2. 目录结构的折叠侧边栏

目录结构的折叠侧边栏的外观和使用类似于资源管理器中的目录管理。

2.1 QTreeWidget 部件的创建和设置

使用 QtDesigner 建立目录结构的折叠侧边栏的步骤如下:

  • (1)以上文 uiDemo8.ui 为基础,在图形窗口的左侧创建一个垂直布局器 leftLayout,在图形窗口的中间和右侧创建一个堆叠布局器 stackedWidget。堆叠布局的页面布局和设计详见上文,本文不作赘述。
  • (2)在 QtDesigner 左侧工具栏 “ItemWidgets” 类中,选择树窗口部件 “Tree Widget”,将其拖动至垂直布局器 leftLayout 中,就创建一个树窗口部件,将部件名(objectName)设为 “treeWidget”。
  • (3)树窗口部件 “treeWidget” 的属性编辑:
    • 树窗口部件 “treeWidget” 的大小、位置属性编辑与其它控件类似,选中后可以用鼠标拖动拉伸,或在属性编辑器中修改;
    • 鼠标选中树结构控件 “treeWidget”,右键唤出下拉菜单,选择 “编辑项目”,弹出 “编辑树窗口部件” 对话框;
    • 对话框中 “列©” 选项:“treeWidget” 可以设置一列或多列,本例中只需要设置一列,编辑列名,如:“章节目录”;
    • 对话框中 “项目(I)” 选项:通过对话框左下方的按钮添加具体的目录信息,其中 “+” 用于添加项目,"-" 用于删除项目,“L+” 用于建立并添加下一级的目录信息。编辑完成后点击 “OK” 保存。

本例中树窗口部件 “treeWidget” 的属性编辑状态如下图所示。


2.2 QTreeWidget 侧边栏的信号/槽连接

上节在图形界面中创建了树窗口部件 “treeWidget”。在 QtDesigner 中可以通过 “预览”(Ctrl+R)功能预览应用程序的窗口效果。

在应用程序中的图形窗口中,默认显示根目录层级信息,不显示次级目录的信息。带有下级目录的项目,其左侧有一个 “>” 符号。鼠标点击目录选项前的三角符号,将展开其下一级目录的内容。

通常我们希望用户在点击侧边栏的目录项目时,应用程序能自动执行该项目的操作,这就需要通过编程实现信号/槽的连接。

对树窗口部件 “treeWidget”,可以将鼠标单击或双击作为触发信号连接到槽函数。例如,点击树窗口部件的目录项 item 时触发信号 itemClicked,执行自定义的槽函数 click_treeWidget()。

注意 itemClicked(QTreeWidgetItem*,int) 中的参数 int 不可缺少,即使不使用参数也必须传入,因此自定义槽函数 click_treeWidget() 定义时必须带有该参数,否则程序报错。

但是,树窗口部件 “treeWidget” 是以其整体作为一个控件,不能将目录中每一个项目(item)的鼠标单击或双击作为触发信号连接到一个槽函数,进而执行每个项目各自定义的功能操作。因此,需要在槽函数中判别鼠标所点击的当前项 currentItem,然后再分别执行对应的操作。

具体地,使用 self.treeWidget.currentItem() 可以获得当前项 Item,也可以通过 itemClicked() 传入的参数获得当前项 Item。参见如下例程:

# 建立信号/槽连接,点击按钮事件发射 triggered 信号,执行相应的槽函数
# self.treeWidget.clicked.connect(self.onTreeClicked)
self.treeWidget.itemClicked.connect(self.click_treeWidget)

def click_treeWidget(self, item, column):  # 点击 treeWidget 触发
    # item = self.treeWidget.currentItem()
    print('key = {}\\tvalue = {}'.format(item.text(0), item.text(1)))

本段例程中的槽函数所执行的任务是,显示鼠标点击的当前项 item 的文本 “item.text(0)” ,以示范如何判别鼠标所点击的当前项 Itme。如果希望完成其它任务,可以将 item 作为索引参数,触发信号连接对应的任务处理槽函数,或者直接调用对应的任务处理子程序。


2.3 QTreeWidget 侧边栏的应用程序

本节给出 QTreeWidget 侧边栏的主程序 GUIdemo10.py,包括建立信号/槽连接的程序。

GUIdemo10.py 所调用的 uiDemo10.py,是上节中在 PyDesigner 设计的图形界面 uiDemo.ui,通过 PyUIC 转化而生成的。

本例程在左下方文本框内显示了鼠标点击的当前项 currentItem 的文本内容,示范可以由此获得当前项 Item。鼠标每点击一次/一个树窗口部件 “treeWidget” 中的目录项,都会触发槽函数获得当前项 Item,并在程序窗口的左下方的文本框中显示相应的目录项文本。

如果需要在点击目录时执行其它操作,那就接着编出其它操作的程序实现吧。

# GUIdemo10.py
# Demo10 of GUI by PyQt5 (treeWidget)
# Copyright 2021 youcans, XUPT
# Crated:2021-10-20

import sys, math, sip
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from uiDemo10 import Ui_MainWindow  # 导入 uiDemo10.py 中的 Ui_MainWindow 界面类

class MyMainWindow(QMainWindow, Ui_MainWindow):  # 继承 QMainWindow 类和 Ui_MainWindow 界面类
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)  # 初始化父类
        self.setupUi(self)  # 继承 Ui_MainWindow 界面类

        self.treeWidget.itemClicked.connect(self.click_treeWidget)  # 点击 treeWidget 触发

    def click_treeWidget(self, item, column):  # 点击 treeWidget 触发
        # item = self.treeWidget.currentItem()  # 获得当前项 Item
        # if item != None:  # 根据 item 选择执行其它操作

        print('key = {}\\tvalue = {}'.format(item.text(0), item.text(1)))
        self.plainTextEdit.appendPlainText("Click: treeWidget")
        self.plainTextEdit.appendPlainText("  key :{}".format(item.text(0)))


if __name__ == '__main__':
    app = QApplication(sys.argv)  # 在 QApplication 方法中使用,创建应用程序对象
    myWin = MyMainWindow()  # 实例化 MyMainWindow 类,创建主窗口
    myWin.show()  # 在桌面显示控件 myWin
    sys.exit(app.exec_())  # 结束进程,退出程序


3. 垂直菜单结构折叠侧边栏

垂直菜单结构的折叠侧边栏类似于多级菜单管理,可以实现手风琴、滑动菜单、按键列表形式的侧边栏。

3.1 QToolBox 部件的创建和设置

使用 QtDesigner 建立垂直菜单结构的折叠侧边栏的步骤如下:

  • (1)以上文 uiDemo8.ui 为基础,在图形窗口的左侧创建垂直菜单结构的折叠侧边栏,在图形窗口的中间和右侧创建一个堆叠布局器 stackedWidget。堆叠布局的页面布局和设计详见上文,本文不作赘述。
  • (2)在 QtDesigner 左侧工具栏 “Containers” 类中,选择抽屉部件 “Tool Box”,将其拖动至图形窗口的左侧的适当位置,就创建一个垂直菜单部件,将部件名(objectName)设为 “toolBox”。
    • 新建的垂直菜单部件 “toolBox” 中建立了两个菜单形状的页面,显示为 “Page 1”、“Page 2”,相当于一级菜单的显示内容;
    • 添加菜单页面:鼠标选中垂直菜单部件 “toolBox”,右键唤出下拉菜单,选择 “插入页” ->“在当前页之后/前”,可以插入菜单页面;
    • 整理菜单页面:鼠标选中垂直菜单部件 “toolBox”,右键唤出下拉菜单,选择 “页 *” 可以删除菜单页面,选择 “改变页次序” 可以唤出对话框改变各页面的顺序;
    • 切换当前菜单项:在编辑或使用状态下,都可以点击每个菜单项而将其切换为当前项。当前项的下方有一块空白区域可以插入下级菜单或控件,而非当前项的菜单栏是折叠的。
  • (3)垂直菜单部件 “toolBox” 的属性编辑:
    • 垂直菜单部件 “toolBox” 的大小、位置属性编辑与其它控件类似,选中后可以用鼠标拖动拉伸,或在属性编辑器中修改;
    • 鼠标选中垂直菜单部件 “toolBox”,点击 “Page 1” 后从 QtDesigner 右侧的 “属性编辑器” 中找到 QToolBox -> currentItemName 可以修改当前项 “Page 1” 的 objectName(该属性不是所显示的文本内容,不支持中文)、QToolBox -> currentItemText 修改当前项 “Page 1” 的显示内容(支持中文);
    • 类似地,鼠标选中垂直菜单部件 “toolBox”,点击 “Page 2”、… 后可以在 QtDesigner 右侧的 “属性编辑器” 中修改当前项 “Page 2”、… 的 objectName 及显示内容 “currentItemText”;
  • (4)创建下级菜单控件:
    • 垂直菜单部件 “toolBox” 只建立一级菜单(根目录),并不建立下级菜单;
    • 建立下级菜单控件:点击 “toolBox” 中的菜单项将其切换为当前项,当前项的下方出现一块空白区域,在该空白区域内可以自由添加布局、容器或控件。
    • 本例中向 “toolBox” 中的每个菜单项添加一个垂直布局器(Vertical Layout),再向该垂直布局器中插入一个或多个按键控件(Push Button)作为二级菜单。

上述的创建垂直菜单部件和二级菜单控件的步骤如下图所示:


3.2 QToolBox 侧边栏的信号/槽连接

上节所建立垂直菜单结构的折叠侧边栏,可折叠的一级菜单是由抽屉部件 “Tool Box” 实现的,而二级菜单是由一组按键控件 “Push Button” 实现的。

如同堆叠布局各页面中的每个按键控件是相互独立的不同的控件,垂直菜单结构中的二级菜单按键控件也都是相互独立的不同的控件。这些控件必须具有唯一的 objectName,但可以具有相同的显示内容 “Button Text”。换句话说,在不同的一级菜单项下可能会出现相同显示内容的按键控件,但将被定义为不同 objectName 的按键控件。

由于这种垂直菜单结构的二级菜单都是独立的按键控件,因此建立信号/槽连接的方法,与图形界面中的普通控件的操作是相同的。既可以在 QtDesigner 中编辑建立信号/槽连接,也可以在 Python 程序中通过编程实现。

在 QtDesigner 中编辑建立信号/槽连接的方法,详见 Python 小白从零开始 PyQt5 项目实战(3)信号与槽的连接,结果如下图所示。


在 Python 程序中编程实现二级菜单按键控件的信号/槽连接的例程如下,将 QtDesigner 建立的 UI 设计文件转换为 .py 后也可以得到该程序。

    # 建立信号/槽连接,点击按钮事件执行相应的子程序 click_pushButton
    self.actionQuit.triggered.connect(MainWindow.close)
    self.actionHelp.triggered.connect(MainWindow.trigger_actHelp)
    self.pushButton_01.clicked.connect(MainWindow.click_pushButton_01)
    self.pushButton_02.clicked.connect(MainWindow.click_pushButton_02)
    self.pushButton_03.clicked.connect(MainWindow.click_pushButton_03)
    self.pushButton_04.clicked.connect(MainWindow.click_pushButton_04)
    self.pushButton_05.clicked.connect(MainWindow.click_pushButton_05)
    self.pushButton_06.clicked.connect(MainWindow.click_pushButton_06)
    self.pushButton_07.clicked.connect(MainWindow.click_pushButton_07)
    self.pushButton_08.clicked.connect(MainWindow.click_pushButton_08)
    self.pushButton_09.clicked.connect(MainWindow.click_pushButton_09)
    self.pushButton_10.clicked.connect(MainWindow.click_pushButton_10)

对二级菜单按键控件建立了信号/槽连接,就可以在相应的槽函数执行所需的各种操作,而不需要任何判别或控制程序。

当然,如果执行的操作需要使用窗口中的堆叠布局,仍然需要进行堆叠窗口控件的页面控制,以选择所需的任务场景,但这与侧边栏的菜单选项无关。

垂直菜单结构的折叠侧边栏的程序图形窗口如下图所示。至此,我们已经完成了一个比较完整的应用程序的 UI 和程序框架。




3.3 QToolBox 侧边栏的应用程序

以下是主程序完整的例程,略去了部分操作的子程序,并不影响侧边栏的菜单折叠和切换功能。

# GUIdemo11.py
# Demo11 of GUI by PyQt5
# Copyright 2021 youcans, XUPT
# Crated:2021-10-20

import sys, math, sip
import numpy as np      # 导入 numpy 并简写成 np

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from uiDemo11 import Ui_MainWindow  # 导入 uiDemo9.py 中的 Ui_MainWindow 界面类

class MyMainWindow(QMainWindow, Ui_MainWindow):  # 继承 QMainWindow 类和 Ui_MainWindow 界面类
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)  # 初始化父类
        self.setupUi(self)  # 继承 Ui_MainWindow 界面类

    def click_pushButton_01(self):  # 点击 pushButton_01 触发
        self.lineEdit.setText("1. 几何变换")
        self.plainTextEdit.appendPlainText("1.1 图像平移")
        self.stackedWidget.setCurrentIndex(0)  # 打开 stackedWidget > page_0
        self.label_1.setPixmap(QtGui.QPixmap("../image/fractal01.png"))
        return

    def click_pushButton_02(self):  # 点击 pushButton_02 触发
        ...

    ...
    def click_pushButton_10(self):  # 点击 pushButton_10 触发
        ...
        
if __name__ == '__main__':
    app = QApplication(sys.argv)  # 在 QApplication 方法中使用,创建应用程序对象
    myWin = MyMainWindow()  # 实例化 MyMainWindow 类,创建主窗口
    myWin.show()  # 在桌面显示控件 myWin
    sys.exit(app.exec_())  # 结束进程,退出程序


4. 项目总结

在本系列中,我们从 PyQt5 的安装开始,先后介绍了基本应用:菜单和工具栏、基本控件,核心机制:信号与槽连接、高级应用:布局管理、窗口切换和折叠侧边栏,并通过项目实战案例介绍各种应用的详细操作过程,给出相关例程。

PyQt5 的体系庞大复杂,可以创造丰富多彩的图形界面。作者也是初学乍练,以实战过程为小白解说分享。对于 Python 小白来说,通过本系列的学习,可以初步掌握和快速建立一个较为完整和通用的图形界面程序框架。

本系列的内容到此就暂告一段落。

下一篇文章是本系列全文汇总,并给出通用图形界面程序框架的完整例程,可以为小白提供一个设计模板。有需要的朋友,请在文后评论区留言。


【本节完】


版权声明:

欢迎关注『Python 小白从零开始 PyQt5 项目实战 @ Youcans』 原创作品

原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/120834085)

Copyright 2021 youcans, XUPT

Crated:2021-10-20


欢迎关注『Python 小白从零开始 PyQt5 项目实战 @ Youcans』系列,持续更新中
Python 小白从零开始 PyQt5 项目实战(1)安装与环境配置
Python 小白从零开始 PyQt5 项目实战(2)菜单和工具栏
Python 小白从零开始 PyQt5 项目实战(3)信号与槽的连接
Python 小白从零开始 PyQt5 项目实战(4)基本控件
Python 小白从零开始 PyQt5 项目实战(5)布局管理
Python 小白从零开始 PyQt5 项目实战(6)窗口切换的堆叠布局
Python 小白从零开始 PyQt5 项目实战(7)折叠侧边栏的实现

以上是关于Python 小白从零开始 PyQt5 项目实战折叠侧边栏的实现的主要内容,如果未能解决你的问题,请参考以下文章

Python 小白从零开始 PyQt5 项目实战菜单和工具栏

Python 小白从零开始 PyQt5 项目实战布局管理

Python 小白从零开始 PyQt5 项目实战窗口切换的堆叠布局

Python 小白从零开始 PyQt5 项目实战窗口切换的堆叠布局

Python 小白从零开始 PyQt5 项目实战信号与槽的连接

Python 小白从零开始 PyQt5 项目实战汇总篇(完整例程)