常用控件4

大家可以先根据我们网站自学。

如果自学速度慢、难点搞不定,欢迎来报 实战班 学习。
白月黑羽 1对1连线 讲解答疑,大量练习实战,学习效果是自学没法比的。还有商业项目实战,可以写入简历。

点击这里查看实战班介绍 咨询微信:18502556834

树控件

QTreeWidget 树控件 树控件, 是和 QTreeWidgetItem 树节点控件 结合使用的。

如下图所示

image

QTreeWidget 官网介绍

QTreeWidgetItem 官网介绍

说明

树控件用来展示树状层级结构的数据,典型例子有: 文件目录结构、知识点结构

设置属性

如果用 Qt 设计师 工具 制作界面,首先应该设置好 QTreeWidget 的一些属性,如下

image

其中,常见的设置是 :

  • 设置有几个column ,也就是有几列,

    双击树控件,就可以编辑列名,如下图

    image

  • 可以设置列标头 是否可见

添加节点

设置好 QTreeWidget 的属性以后,代码中加载界面资源文件,就可以在树上添加节点了,如下代码所示

    # 获取树控件的不可见根节点
    # 变量tree对应的是 QTreeWidget对象
    root = tree.invisibleRootItem()

    # 准备一个folder节点
    folderItem = QTreeWidgetItem()
    # 创建图标对象  from PySide2.QtGui import QIcon
    folderIcon = QIcon("./Images/folder.png")
    # 设置节点图标
    folderItem.setIcon(0, folderIcon)
    # 设置该节点  第1个column 文本
    folderItem.setText(0, '白月黑羽学员李辉')
    # 添加到树的不可见根节点下,就成为第一层节点
    root.addChild(folderItem)
    # 设置该节点为展开状态
    folderItem.setExpanded(True)

    # 准备一个 叶子 节点
    leafItem = QTreeWidgetItem()
    leafIcon = QIcon("./Images/leaf.png")
    # 设置节点图标
    leafItem.setIcon(0, leafIcon)
    # 设置该节点  第1个column 文本
    leafItem.setText(0, '作业 - web自动化1')
    # 设置该节点  第2个column 文本
    leafItem.setText(1, '提交日期20200101')
    # 添加到 叶子节点 到 folerItem 目录节点下
    folderItem.addChild(leafItem)

上面的程序运行后,大概的结果图如下

image

注意:

  • 每个 节点 都是 QTreeWidgetItem 对象

  • 添加节点 必须通过 该节点的 父节点

    可以使用 addChild 方法,添加到最后

    也可以使用 insertChild 方法,插入到指定位置,比如

    folderItem.insertChild(2, leafItem)
    

    就插入到 第3个 子节点的位置上,因为第1个子节点的索引是0。

  • 如果控件宽度不够,字符串会显示为省略号。

删除节点

删除 QTreeWidget 的节点,也是 通过其父节点进行的。

示例代码如下:

    # 获取当前用户点选的节点
    currentItem = tree.currentItem()

    # 如果没有当前选中节点
    if not currentItem:
        return
    
    # 找到改节点的父节点
    parentItem = currentItem.parent()
    # 如果没有父节点,就是不可见父节点
    if not parentItem:
        parentItem = tree.invisibleRootItem()
    # 删除该节点
    parentItem.removeChild(currentItem)

遍历树节点

下面是一段遍历树节点,保存数据的示例代码

    # 递归调用函数,完成整个树的遍历
    def iterateFunc(parent,dataTree):
        child_count = parent.childCount()
        for i in range(child_count):
            item = parent.child(i)

            # 保存这个节点item的信息到字典对象中
            subDictNode = {}
            dataTree.append(subDictNode)
            subDictNode['data'] = item.data
            subDictNode['children'] = []

            # 对该子节点递归调用遍历处理函数
            iterateFunc(item,subDictNode['children'])

    # 获取不可见根节点
    root = tree.invisibleRootItem()
    # 用嵌套列表来对应树的数据结构,方便保存到文件
    dataTree = [] 
    iterateFunc(root,dataTree)
    
    # 序列化到json文件,保存
    jsonStr = json.dumps(dataTree,ensure_ascii=False,indent=2)
    with open('data.json','w',encoding='utf8') as f:
        f.write(jsonStr)

信号处理

QTreeWidget 常见的信号有:单击节点、双击节点、当前节点变动 等等。

详细信息参考官方文档

大家可以根据自己的需要,定义信号处理函数

修改节点

修改节点列数据

要直接双击修改节点文本,就是如下所示

image

首先必须设置节点为 可编辑 ItemIsEditable

可以在创建节点的时候设置,如下代码所示

# 准备一个folder节点
folderItem = QTreeWidgetItem()
folderItem.setIcon(0, folderIcon)
folderItem.setText(0, '白月黑羽学员李辉')

# 设置该节点在以前的flag基础上,多一个可编辑 ItemIsEditable
folderItem.setFlags(folderItem.flags()  | QtCore.Qt.ItemIsEditable)

这样设置好以后,可编辑的节点内部改变后,其所属 QTreeWidget 就会触发 itemChanged 信号

我们应该定义该信号的处理函数,如下所示


class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.ui =  Ui_MainWindow()

        # 初始化界面
        self.ui.setupUi(self)
        self.loadTree()

        # 必须先加载树,然后再设置信号处理,
        # 否则加载过程也会触发 itemChanged 信号
        self.ui.notesTree.itemChanged.connect(self.itemChanged)


    def itemChanged(self, item, column):
        # 参数 item 是修改的 节点 QTreeWidgetItem对象
        # 参数 column 是修改的 列号

        newText = item.text(column)

        # 根据改变的 column 得知是哪个数据修改了
        # 保存到对应的数据
        if column == 0:
            item.title = newText
        elif column == 1:
            item.deadline = newText            

修改节点关联数据

QTreeWidget 节点 可以 关联 各种类型的数据。

所以节点对应的数据信息 没有固定格式,由程序自身决定。

要修改节点的信息,一个通用的方法是

  • 定义双击节点 信号 itemDoubleClicked 的处理函数

  • 在处理函数里面 打开一个 信息输入框,用户可以在里面输入新的信息,

    包括 节点显示的column信息,节点关联的其他任意信息

    然后,把column信息通过 QTreeWidgetItem 对象的 setText 方法更新到界面上。

    其他关联信息,进行各种相应的处理。

提示框

QMessageBox 类可以用来弹出各种提示框

官网介绍

该类可以通过一系列静态方法,显示 如下弹出框

  • 错误报告

image

使用 critical 方法

QMessageBox.critical(
    self.ui,
    '错误',
    '请选择爬取数据存储路径!')
  • 警告

image

使用 warning 方法

QMessageBox.warning(
    self.ui,
    '阅读太快',
    '阅读客户协议必须超过1分钟')
  • 信息提示

image

使用 information 方法

QMessageBox.information(
    self.ui,
    '操作成功',
    '请继续下一步操作')

也可以使用 about 方法

QMessageBox.about(
    self.ui,
    '操作成功',
    '请继续下一步操作')
  • 确认继续

image

使用 question 方法

choice = QMessageBox.question(
    self.ui,
    '确认',
    '确定要删除本文件吗?')

if choice == QMessageBox.Yes:
    print('你选择了yes')
if choice == QMessageBox.No:
    print('你选择了no')

输入对话框

QInputDialog 输入对话框 只让用户输入一行数据信息,比如 姓名、年龄等。

可以方便的用来获取简单的信息。

image

QTreeWidget 官网介绍


比如

from PySide2.QtWidgets import QInputDialog,QLineEdit

# 返回值分别是输入数据 和 是否点击了 OK 按钮(True/False)
title, okPressed = QInputDialog.getText(
    self, 
    "输入目录名称",
    "名称:",
    QLineEdit.Normal,
    "")

if not okPressed:
    print('你取消了输入')

常用的方法有:

  • getText

    弹出对话框,让用户输入 单行文本

  • getMultiLineText

    弹出对话框,让用户输入 多行文本

  • getInt

    弹出对话框,让用户输入 整数

  • getItem

    弹出对话框,让用户选择 选项

    items = ["春天", "夏天", "秋天", "冬天"]
    
    item, ok = QInputDialog().getItem(self, 
                                      "请选择",
                                      "季节:", 
                                      items, 
                                      0, 
                                      False)
    if ok and not item.isEmpty():
        itemLabel.setText(item)
    

菜单

可以在 Qt Designer上很方便的添加菜单,如下所示

image

点击菜单的信号是 triggered, 处理点击菜单的的代码如下

self.ui.actionOpenFile.triggered.connect(self.openPageFile)

工具栏

在 Qt 设计师上添加工具栏,可以右键点击 Main Window 类型的窗体空白处,如下所示

image

选择添加工具栏


注意,只有 Main Window 类型的窗体,才能添加工具栏,如下

image


添加工具栏后,还要在工具栏上添加图标。

方法是点击右下角 动作编辑器,新建动作,如下图所示

image

然后如下图所示进行设置

image

添加动作成功后,就可以直接拖到工具栏上了。


然后,在代码中定义动作触发后的处理函数,如下所示

self.ui.actionAddNote.triggered.connect(self.actionAddNode)

状态栏

官网介绍

要在状态栏显示文本信息,只需要调用 QStatusBar 的 showMessage 方法

self.ui.statusbar.showMessage(f'打开文件{filePath}')

剪贴板

官网介绍

from PySide2.QtGui import QGuiApplication

cb = QGuiApplication.clipboard()
# 获取剪贴板内容
originalText = cb.text()
# 设置剪贴板内容
clipboard.setText(newText)

上一页
下一页