【Qt】Qt多元素控件深入解析与实战应用:列表(QListWidget)、表格(QTableWidget)与树形(QTreeWidget)结构

文章目录

  • 前言:
  • Qt中多元素控件:
  • 1. List Widget
    • 1.1. 代码示例: 使用 ListWidget
  • 2.Table Widget
    • 2.1. 代码示例: 使用 QTableWidget
  • 3. Tree Widget
    • 3.1. 代码示例: 使用 QTreeWidget
  • 总结:

前言:

在Qt框架中,用户界面的构建是一个至关重要的环节,而其中多元素控件的使用更是构建丰富用户界面的核心。本文将深入探讨Qt中的三种主要多元素控件:List Widget、Table Widget和Tree Widget。通过详细的代码示例和功能解析,本文旨在帮助开发者更好地理解和运用这些控件,以创建具有交互性和功能性的应用程序界面。无论是初学者还是有经验的开发者,都能从本文中获得有价值的信息和启发。

Qt中多元素控件:

Qt 中多元素控件有:
列表QListWidget + QListView
表格: QTableWidget + QTableView
树形QTreeWidget + QTreeView

  • xxWidget 与 xxView 是啥区别?
    xxView 是更底层的实现。
    xxWidget 是 基于 xxView 封装而来的。

此处xxView 是 MVC 结构的一种典型实现 MVC 也是软件开发中,非常经典的 软件结构的组织形式了

M:model 数据
V:view 视图(界面)
C:controller 控制器,数据和是同之间的业务流程

  • xxView 只是负责实现了视图,不负责数据如何存储表述,更不负责数据是同之间的交互。因此,如果使用xxView就需要程序员自己实现 model 和 controller 的部分,就比较麻烦。

  • xxWidget 基于 xxView 同时把 model 和 control 都帮我们实现好了,拿过来就可以使用,人家提供了功能很方便的api,让我们直接就用。

  • xxWidget 使用起来比较方便,但是功能会比较的有限。

  • xxView 使用起来更麻烦一些,但可以根据情况自由 DIY ,实现一些更复杂的功能。

1. List Widget

使用 QListWidget 都能显示一个纵向的列表,形如:
在这里插入图片描述
列表中的每一个元素/每一项就称为一个 Item
更具体的说,通过 QListWidgetItem 类表示的!

在这里插入图片描述
在这里插入图片描述

此处的row参数就表示插入完毕之后的元素在第几行,把新元素插入到第几行之前。

takeItem:take 也是用来表示 “删除” 术语 (erase、remove、delete、take)

在这里插入图片描述

1.1. 代码示例: 使用 ListWidget

先往这里添加一些元素

  • 添加方式 1:
ui->listWidget->addItem("C++");
ui->listWidget->addItem("Java");
ui->listWidget->addItem("Python");
  • 添加方式 2:
ui->listWidget->addItem(new QListWidgetItem("C++"));
ui->listWidget->addItem(new QListWidgetItem("Java"));
ui->listWidget->addItem(new QListWidgetItem("Python"));

QListWidgetItem 中, 可以设置字体属性,设置图标,设置文字大小, 设置是否被选中等状态。

  • 添加方式 3 : 通过图形化界面进行添加
    在这里插入图片描述
    通过图形化界面,右键 QListWidget,选择编辑项目就可以之间添加内容。
  • 如果这里初始化内容是固定的,此时你通过那种方式来初始化都可以。
  • 如果这里的内容不是固定的,就要通过 读取文件/读取网络 来构造数据,就需要通过代码的方式来添加了。
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 先往这里添加一些元素
    // 添加方式 1
    ui->listWidget->addItem("C++");
    ui->listWidget->addItem("Java");
    ui->listWidget->addItem("Python");

//    // 添加方式 2
//    ui->listWidget->addItem(new QListWidgetItem("C++"));
//    ui->listWidget->addItem(new QListWidgetItem("Java"));
//    ui->listWidget->addItem(new QListWidgetItem("Python"));

    // 添加方式 3 : 通过图形化界面进行添加
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insert_clicked()
{
    // 1. 先获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    // 2. 添加到 QListWidget 中
    ui->listWidget->addItem(text);
}

void Widget::on_pushButton_delete_clicked()
{
    // 1. 先获取到被选中的元素是哪个
    int row = ui->listWidget->currentRow();
    if (row < 0) {
        return;
    }
    // 2. 按行号来删除元素
    ui->listWidget->takeItem(row);
}

void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    // 通过这个槽函数来感知到变化
    if (current != nullptr) {
        qDebug() << "当前选中的元素:" << current->text();
    }
    if (previous != nullptr) {
        qDebug() << "上选中的元素:" << previous->text();
     }

}

在这里插入图片描述

2.Table Widget

使用 QTableWidget 表示一个表格控件,一个表格中包含若干行,每一行又包含若干列。
表格中的每一个单元,是一个 QTableWidgetItem 对象。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1. 代码示例: 使用 QTableWidget

在这里插入图片描述

如果当前表格中的数据是固定的,完全可以通过图形化的方式来进行编辑,但实际开发中,很多时候数据是从 文件/网络 加载过来的, 此时通过图形化编辑就不合适了。

  • 通过代码编写:
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 创建 3 行
    ui->tableWidget->insertRow(0);
    ui->tableWidget->insertRow(1);
    ui->tableWidget->insertRow(2);

    // 创建 3 个列
    ui->tableWidget->insertColumn(0);
    ui->tableWidget->insertColumn(1);
    ui->tableWidget->insertColumn(2);

    // 给 3 个列设定列名(设施水平方向的表头)
    ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("学号"));
    ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("姓名"));
    ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("年龄"));

    // 给表格中添加数据
    ui->tableWidget->setItem(0, 0, new QTableWidgetItem("1001"));
    ui->tableWidget->setItem(0, 1, new QTableWidgetItem("张三"));
    ui->tableWidget->setItem(0, 2, new QTableWidgetItem("20"));

    ui->tableWidget->setItem(1, 0, new QTableWidgetItem("1002"));
    ui->tableWidget->setItem(1, 1, new QTableWidgetItem("李四"));
    ui->tableWidget->setItem(1, 2, new QTableWidgetItem("19"));

    ui->tableWidget->setItem(2, 0, new QTableWidgetItem("1003"));
    ui->tableWidget->setItem(2, 1, new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2, 2, new QTableWidgetItem("21"));
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insertLine_clicked()
{
    // 需要知道当前一共有多少行
    int rowCount = ui->tableWidget->rowCount();
    // 在最后一行之后新增行
    // 注意此处的参数是 “下标”,表示你新增之后这一行是第几行
    ui->tableWidget->insertRow(rowCount);
}

void Widget::on_pushButton_deleteLine_clicked()
{
    // 获取选中的行号
    int curRow = ui->tableWidget->currentRow();
    // 删除这一行
    ui->tableWidget->removeRow(curRow);
}

void Widget::on_pushButton_insertColumn_clicked()
{
    // 先获取到一共有几列
    int colCount = ui->tableWidget->columnCount();
    // 在对应的位置新增这一列
    ui->tableWidget->insertColumn(colCount);
    // 设置列名(从输入框中获取到)
    const QString& text = ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(colCount, new QTableWidgetItem(text));
}

void Widget::on_pushButton_Column_clicked()
{
    // 获取到选中的列号
    int curCol = ui->tableWidget->currentColumn();
    // 删除这一列
    ui->tableWidget->removeColumn(curCol);
}

在这里插入图片描述

3. Tree Widget

使用 QTreeWidget 表示一个树形控件。里面的每个元素,都是一个 QTreeWidgetItem,每个QTreeWidgetItem 可以包含多个文本和图标,每个文本/图标为一个列。
可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加子节点, 从而构成树形结构。
在这里插入图片描述
QTreeWidget 控件虽然是树形结构,但是这个树形结构,没有体现出根节点,是从根节点的下一层子节点开始计算的。
在这里插入图片描述
针对顶层节点来说,这里也是一个类似于 “List” 这样的结构 !
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1. 代码示例: 使用 QTreeWidget

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 设置根节点的名字
    ui->treeWidget->setHeaderLabel("动物");

    // 设置顶层节点
    QTreeWidgetItem* item1 = new QTreeWidgetItem();
    // 每个节点都可以设置多个列,此处为了简单就只设置一列
    item1->setText(0, "猫");
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item1);

    // 设置顶层节点
    QTreeWidgetItem* item2 = new QTreeWidgetItem();
    // 每个节点都可以设置多个列,此处为了简单就只设置一列
    item2->setText(0, "狗");
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item2);

    // 设置顶层节点
    QTreeWidgetItem* item3 = new QTreeWidgetItem();
    // 每个节点都可以设置多个列,此处为了简单就只设置一列
    item3->setText(0, "鸟");
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item3);


    // 添加一些子节点
    QTreeWidgetItem* item4 = new QTreeWidgetItem();
    item4->setText(0, "中华田园猫");
    item1->addChild(item4);

    QTreeWidgetItem* item5 = new QTreeWidgetItem();
    item5->setText(0, "布偶猫");
    item1->addChild(item5);

    QTreeWidgetItem* item6 = new QTreeWidgetItem();
    item6->setText(0, "暹罗猫");
    item1->addChild(item6);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_pushButton_insertTopLeveItem_clicked()
{
    // 获取到输入框中的内容
    const QString& text = ui->lineEdit->text();
    // 判断输入框是否为空
    if (text.isEmpty()) {
        return;
    }
    // 构造一个 QTreeWidetITem
    QTreeWidgetItem * item = new QTreeWidgetItem();
    item->setText(0, text);
    // 添加到顶层节点中
    ui->treeWidget->addTopLevelItem(item);
}

void Widget::on_pushButton_insertItem_clicked()
{
    // 获取到当前选中的节点
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if (currentItem == nullptr) {
        return;
    }
    // 获取到输入框的内容
    const QString& text = ui->lineEdit->text();
    // 判断输入框是否为空
    if (text.isEmpty()) {
        return;
    }
    // 构造一个 QTreeWidgetItem
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0, text);
    // 插入到选中节点的子节点中
    currentItem->addChild(item);
}

void Widget::on_pushButton_deleteItem_clicked()
{
    // 获取到选中元素
    QTreeWidgetItem* currentItem = ui->treeWidget->currentItem();
    if (currentItem == nullptr) {
        return;
    }
    // 删除选中元素, 需要先获取到父元素,通过父元素进行删除
    QTreeWidgetItem* parent = currentItem->parent();
    if (parent == nullptr) {
        // 顶层元素
        int index = ui->treeWidget->indexOfTopLevelItem(currentItem);
        ui->treeWidget->takeTopLevelItem(index);
    } else {
        // 普通元素
        parent->removeChild(currentItem);
    }
}

在这里插入图片描述

总结:

本文详细介绍了Qt中的三种多元素控件:List Widget、Table Widget和Tree Widget,它们分别用于展示列表、表格和树形结构的数据。通过代码示例,我们展示了如何使用这些控件进行数据的添加、删除和修改操作。同时,也解释了xxWidget与xxView之间的区别,以及它们在MVC架构中扮演的角色。xxWidget提供了封装好的模型和控制器,使得开发者可以快速地实现功能,而xxView则提供了更底层的视图实现,允许开发者有更大的灵活性来自定义功能。

然而,需要注意的是,这些控件默认情况下只将数据保存在内存中,一旦程序重启,之前的数据就会丢失。为了实现数据的持久化,开发者需要编写额外的代码,将数据写入文件,并在程序启动时从文件中加载数据。通过本文的学习,开发者应该能够更加熟练地使用Qt中的多元素控件,并理解如何通过编程实现数据的持久化存储。

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

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

相关文章

mac下安装airflow

背景&#xff1a;因为用的是Mac的M芯片的电脑&#xff0c;安装很多东西都经常报错&#xff0c;最近在研究怎么把大数据集群上的crontab下的任务都配置到一个可视化工具中&#xff0c;发现airflow好像是个不错的选择&#xff0c;然后就研究怎么先安装使用起来&#xff0c;后面再…

Django5+React18前后端分离开发实战05 序列化

Django REST Framework We will use the Django REST Framework to help build our API. 我们会使用 Django REST Framework 框架来构建我们的API。 You can build APIs on your own in Django but it will take a lot of work. 你可以使用Django自己构建API&#xff0c;但是…

【C++进阶】AVL树

0.前言 前面我们已经学习过二叉搜索树了&#xff0c;但如果我们是用二叉搜索树来封装map和set等关联式容器是有缺陷的&#xff0c;很可能会退化为单分支的情况&#xff0c;那样效率就极低了&#xff0c;那么有没有方法来弥补二叉搜索树的缺陷呢&#xff1f; 那么AVL树就出现了&…

nuxt: generate打包后访问资源404问题

现象 使用Nuxt.js开发的个人页面&#xff0c;部署到nginx服务器中&#xff0c;/_nuxt/*.js、/_nuxt/*.css等静态问题不能访问&#xff0c;提示404错误。 而我们的这些资源文件是存在的。 解决方法 加上此处代码进行上下文配置 baseURL: /nuxt/ 此时在nginx配置 /nuxt 代理 lo…

QAnything 1.4.1 中的文档解析

2024年初我们开源了QAnything&#xff0c;一个基于检索增强生成式应用&#xff08;RAG&#xff09;的本地知识库问答系统。对于本地知识库&#xff0c;QAnything支持多种格式的文档输入&#xff0c;允许用户上传包括PDF、图片、Word、PowerPoint、Excel、TXT&#xff0c;甚至音…

m1系列芯片aarch64架构使用docker-compose安装rocketmq5.0以及运维控制台

之前看到 DockerHub 上有大佬制作了 m1 芯片, aarch64架构的 rocketmq 镜像, 所以就尝试的安装了下, 亲测可用: 一. docker-compose.yml 文件命令 volumes 挂载目录需要换成自己的目录 注意 depends_on 标签, broker 和 console 的 启动要晚于 namesrv, 因为 broker 需要注册…

SpringBoot 集成 ChatGPT(附实战源码)

建项目 项目结构 application.properties openai.chatgtp.modelgpt-3.5-turbo openai.chatgtp.api.keyREPLACE_WITH_YOUR_API_KEY openai.chatgtp.api.urlhttps://api.openai.com/v1/chat/completionsopenai.chatgtp.max-completions1 openai.chatgtp.temperature0 openai.cha…

VSCode配置Lua5.4安装

参考&#xff1a;VSCode 配置 Lua 开发环境(清晰明了)_lua vscode-CSDN博客 1.下载 Lua Binaries Download (sourceforge.net) 2.配置环境变量 解压放到某文件夹&#xff1a; 环境变量&#xff1a; 3.VSCode安装插件 4.配置 5.测试

【C语言刷题系列】求一个数组中两个元素a和b的和最接近整数m

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;C语言刷题系列 目录 一、问题描述 二、解题思路 解题思路&#xff1a; 解题步骤: 三、C语言代码实现及测试 一、问题描述 给定一…

全栈式数据统计:SqlAlchemy怎样连接MsSql Server获取视图列表

1.源代码 #-----------获取数据库视图列表----------------------------- # -------密码含特殊字符使用 from urllib.parse import quote_plus as urlquotefrom sqlalchemy import create_engine, MetaData, inspect# 替换为你的数据库连接字符串 DRIVER "ODBC Driver 1…

数组序号Spinner

使用Spnner代替编辑框&#xff0c;只能选择已有的&#xff0c;不会越界&#xff0c;大大简化了代码。 String[] SA new String[list.size()]; for (int i0; i<SA.length; i) {SA[i] String.valueOf(i); } ArrayAdapter<String> adapter1 new ArrayAdapter<>(…

【2024软考】史上最全!软考刷题+解析大合集(9万字全手工打,货真价实)

计算机基础知识 1.中断向量表用来保存各个中断源的中断服务程序的入口地址。当外设发出中断请求信号&#xff08;INTR&#xff09;以后&#xff0c;由中断控制器&#xff08;INTC&#xff09;确定其中断号&#xff0c;并根据中断号查找中断向量表来取得其中断服务程序的入口地…

读论文 | Small object detection model for UAV aerial image based on YOLOv7

目录 1、前言 2、摘要 3、论文的方法 3.1 方法描述 3.2 方法改进 3.3 本论文的模型图 3.4 本文的数据集&#xff1a; 3.5 论文实验 3.6 解决的问题 3.7 论文总结 &#xff08;1&#xff09;文章优点 &#xff08;2&#xff09;方法创新点 &#xff08;3&#xff0…

基于Tensorflow卷积神经网络人脸识别公寓人员进出管理系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 随着科技的快速发展和智能化水平的提高&#xff0c;公寓管理面临着越来越多的挑战。传统的公寓…

Django 安装步骤

步骤如下 打开cmd输入命令行 pip install django上图代表已经安装好了。但是里面的warning必须得将路径弄好&#xff0c;不然是运行不了 创建django项目 去到VS Code里&#xff0c;进入Terminal 页面&#xff0c;运行下面的命令 django-admin startproject [自己项目名称]就…

基于地理坐标的高阶几何编辑工具算法(4)——线分割面

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理 工具步骤 选中待分割面&#xff0c;点击“线分割面”工具&#xff0c;绘制和面至少两个交点的线&#xff0c;双击结束&#xff0c;执行分割操作 应用场景 快速切分大型几何面&#xff0c;以降低面的复杂度&…

Scrapy顺序执行多个爬虫

Scrapy顺序执行多个爬虫 有两种方式&#xff1a; 第一种&#xff1a;bat方式运行 新建bat文件 cd C:\python_web\spiders\tiktokSelenium & C: & scrapy crawl spider1 & scrapy crawl spider2 & scrapy crawl spider3 & scrapy crawl spider4 第二种&a…

小猪APP分发:一站式托管服务,轻松玩转应用市场

在当今移动应用爆炸式增长的时代&#xff0c;开发者们面临的挑战不再仅限于创意的火花和代码的实现&#xff0c;更在于如何让精心打造的应用快速触达广大用户。这正是小猪APP分发www.appzhu.net应运而生的背景——作为一个全面、高效的APP托管服务分发平台&#xff0c;它为开发…

解决docker中container运行闪退终止的问题

在运行bindmount-test时&#xff0c;点击完运行按钮后闪退结束运行。 第一步查看log日志&#xff1a; 2024-05-18 23:46:18 Error: Cannot find module /app/nodemon 2024-05-18 23:46:18 at Function.Module._resolveFilename (internal/modules/cjs/loader.js:668:15) …

【Kafka】消息的顺序性、可靠性、幂等性

目录 消息顺序性消息可靠性生产者丢失消息消费者丢失消息Kafka丢失消息 消息幂等性 消息顺序性 消息追加到partition尾部&#xff0c;单个partition是有序的&#xff0c;但多个partition如何进行有序的获取一些消息&#xff1f; 解决方案 一个topic只设置一个partition&…