【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

06-02 536阅读

【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”

绪论​:

本章将通过代码示例详细介绍了Qt中QListWidget、QTableWidget和QTreeWidget三种多元素控件的使用方法与核心功能,涵盖列表的增删操作、表格的行列管理以及树形结构的节点处理。

————————

早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。

【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

多元素控件

Qt 中提供的多元素控件有:

  1. QListWidget
  2. QListView(前两个表示列表结构)

    【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

  3. QTableWidget
  4. QTableView(前两个表示表格结构)

    【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

  5. QTreeWidget
  6. QTreeView(前两个表示树形结构)

    【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

不难发现两种结构中有:xxWidget 和 xxView 之间的区别

  1. xxView 是更底层的实现
  2. xxWidget 是基于 xxView 封装起来的

例如:

  • QTableView 是基于 MVC 设计的控件
    • QTableView ⾃⾝不持有数据(不支持Model)。使⽤ QTableView 的时候需要⽤⼾创建⼀个 Model 对象 (⽐如 QStandardModel ),比较麻烦~
    • 并且把 Model 和 QTableView 关联起来. 后续修改 Model 中的数据就会影响 QTableView 的显⽰
    • 修改 QTableView 的显⽰也会影响到 Model 中的数据(双向绑定).
    • QTableWidget 则是 QTableView 的⼦类, 对 Model 进⾏了封装
      • 所以不需要⽤⼾⼿动创建 Model 对象, 直接就可以往 QTableWidget 中添加数据了
      • 提供了更方便的 api 让自己使用

        不能说谁好谁坏,不同场景使用不同:

        1. 其中 xxxWidget 使用起来比较方便,但功能有限
        2. 而 xxxView 使用起来比较麻烦,但可以自由diy,实现更复杂的功能

        因为他们是两两一组的,所以此处就着重讲解Widget


        List Widget 多元素控件 列表

        使⽤ QListWidget 能够显⽰⼀个纵向的列表. 形如:

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        核⼼属性

        属性说明
        currentRow当前被选中的是第⼏⾏
        count⼀共有多少⾏
        sortingEnabled是否允许排序
        isWrapping是否允许换⾏
        itemAlignment元素的对⻬⽅式
        selectRectVisible被选中的元素矩形(高亮)是否可⻅
        spacing元素之间的间隔

        核⼼⽅法

        ⽅法说明
        addItem(const QString& label)
        addItem(QListWidgetItem *item)
        列表中添加元素(列表中的每个元素/每一项就成为一个item(通过QListWidgetItem 类表示))
        currentItem()返回 QListWidgetItem* 表⽰当前选中的元素
        setCurrentItem(QListWidgetItem* item)设置选中哪个元素
        setCurrentRow(int row)设置选中第⼏⾏的元素
        insertItem(const QString& label, int row)
        insertItem(QListWidgetItem *item, int row)
        在指定的位置插⼊元素 (此处的 row 参数就表示插入完毕之后新的元素在第几行,也就是把新元素插入到第几行之前)
        item(int row)返回 QListWidgetItem* 表⽰第 row ⾏的元素
        takeItem(int row)删除指定⾏的元素, 返回 QListWidgetItem* 表⽰是哪个元素被删除了

        核⼼信号

        ⽅法说明
        currentItemChanged(QListWidgetItem* current, QListWidgetItem* old)选中不同元素时会触发. 参数是当前选中的元素和之前选中的元素.
        currentRowChanged(int)选中不同元素时会触发. 参数是当前选中元素的⾏数.
        itemClicked(QListWidgetItem* item)点击某个元素时触发
        itemDoubleClicked(QListWidgetItem* item)双击某个元素时触发
        itemEntered(QListWidgetItem* item)⿏标进⼊元素时触发

        当选错了多元素控件的时候,可以通过右键选择 “变型为” 进行修改:

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        实操:ListWidget的新增删除列表

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        1. 初始化默认的值

          1. 直接在构造函数中
            1. 通过列表控件调用addItem接口
            2. 添加:C++、Java、Python 子元素
          2. 也能直接在图形化界面中的右击 “列表控件” 选择 “编辑项目” 进行添加

            【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        2. 给新增按钮添加点击信号的槽函数:

          1. 获取到输入框中的内容
          2. 将获取到的内容 添加到QListWidget中
        3. 给删除按钮添加点击信号的槽函数:

          1. 获取被选元素它的行号(currentRow)
          2. 按行号进行删除元素 takeitem
        4. 右键列表新增 currentItemChanged 信号的槽函数(需要添加头文件 QListWidgetItem):

          1. 通过这个槽函数感知变化
          2. 判断current是否为空,不为空则打印:当前选中元素的文本
          3. 并且判断 previous 不为空的话也进行打印文本

        结果:

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        源码:

        #include "widget.h"
        #include "ui_widget.h"
        #include 
        #include 
        Widget::Widget(QWidget *parent)
            : QWidget(parent)
            , ui(new Ui::Widget)
        {
            ui->setupUi(this);
            //添加子元素 addItem
            ui->listWidget->addItem("C++");
            ui->listWidget->addItem("Java");
            ui->listWidget->addItem("Python");
        }
        Widget::~Widget()
        {
            delete ui;
        }
        void Widget::on_pushButton_clicked()
        {
            //获取label内部的数据
            QString text = ui->lineEdit->text();
            //添加到list中
            ui->listWidget->addItem(text);
        }
        void Widget::on_pushButton_2_clicked()
        {
            //获取鼠标选中的行号
            int row = ui->listWidget->currentRow();
            //删除行号的内容 takeitem
            ui->listWidget->takeItem(row);
        }
        void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
        {
            if(previous != nullptr){
                qDebug() 
                qDebug() 
            ui-setupUi(this);
            //新增行
            ui-tableWidget_2->insertRow(0);//默认的即可不用设置行名称
            ui->tableWidget_2->insertRow(1);
            ui->tableWidget_2->insertRow(2);
            //新增列
            ui->tableWidget_2->insertColumn(0);
            ui->tableWidget_2->setHorizontalHeaderItem(0,new QTableWidgetItem("学号"));
            ui->tableWidget_2->insertColumn(1);
            ui->tableWidget_2->setHorizontalHeaderItem(1,new QTableWidgetItem("姓名"));
            ui->tableWidget_2->insertColumn(2);
            ui->tableWidget_2->setHorizontalHeaderItem(2,new QTableWidgetItem("年龄"));
            //添加数据
            ui->tableWidget_2->setItem(0,0,new QTableWidgetItem("1"));
            ui->tableWidget_2->setItem(0,1,new QTableWidgetItem("张三"));
            ui->tableWidget_2->setItem(0,2,new QTableWidgetItem("20"));
            ui->tableWidget_2->setItem(1,0,new QTableWidgetItem("2"));
            ui->tableWidget_2->setItem(1,1,new QTableWidgetItem("李四"));
            ui->tableWidget_2->setItem(1,2,new QTableWidgetItem("28"));
            ui->tableWidget_2->setItem(2,0,new QTableWidgetItem("3"));
            ui->tableWidget_2->setItem(2,1,new QTableWidgetItem("王五"));
            ui->tableWidget_2->setItem(2,2,new QTableWidgetItem("88"));
        }
        Widget::~Widget()
        {
            delete ui;
        }
        //新增一列
        void Widget::on_pushButton_clicked()
        {
            //获取LineEdit中的文本
            QString text = ui->lineEdit->text();
            //获取当前列数
            int ccount = ui->tableWidget->columnCount();
            //添加新列
            ui->tableWidget->insertColumn(ccount);//添加的是下标,所以刚好和个数相同
            //添加列名称
            if(text != nullptr){
                ui->tableWidget->setHorizontalHeaderItem(ccount,new QTableWidgetItem(text));
            }
        }
        //删除选择的列
        void Widget::on_pushButton_2_clicked()
        {
            //获取光标选中的列
            int ccolumn = ui->tableWidget->currentColumn();
            //删除
            ui->tableWidget->removeColumn(ccolumn);
        }
        //新增一行
        void Widget::on_pushButton_3_clicked()
        {
            //获取LineEdit中的文本
            QString text = ui->lineEdit->text();
            //获取当前行数
            int rcount = ui->tableWidget->rowCount();
            //添加新行
            ui->tableWidget->insertRow(rcount);//添加的是下标,所以刚好和个数相同
            //添加行名称
            if(text != ""){
                ui->tableWidget->setVerticalHeaderItem(rcount,new QTableWidgetItem(text));
            }
        }
        //删除选中的行
        void Widget::on_pushButton_4_clicked()
        {
            //获取光标选中的行
            int crow = ui->tableWidget->currentRow();
            //删除行
            ui->tableWidget->removeRow(crow);
        }
        

        Tree Widget

        使⽤ QTreeWidget 表⽰⼀个树形控件。⾥⾯的每个元素, 都是⼀个 QTreeWidgetItem ,每个

        QTreeWidgetItem 可以包含多个⽂本和图标,每个⽂本/图标为⼀个 列。可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加⼦节点, 从⽽构成树形结构。

        对于列数的使用,可以对某子元素进行数据的展示,例如下图的 猫2 列,可以改成猫的年龄/体重,来描述当前子元素的各种属性数据

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        QTreeWidget 的 核⼼⽅法(顶层结点的方法)

        ⽅法说明
        clear清空所有⼦节点
        addTopLevelItem(QTreeWidgetItem* item)新增顶层节点
        topLevelItem(int index)获取指定下标的顶层节点.
        topLevelItemCount()获取顶层节点个数
        indexOfTopLevelItem(QTreeWidgetItem* item)查询指定节点是顶层节点中的下标
        takeTopLevelItem(int index)删除指定的顶层节点. 返回 QTreeWidgetItem* 表⽰被删除的元素
        currentItem()获取到当前选中的节点, 返回 QTreeWidgetItem*
        setCurrentItem(QTreeWidgetItem* item)选中指定节点
        setExpanded(bool)控制 展开/关闭 子节点
        setHeaderLabel(const QString& text)设置 TreeWidget 的 header 名称

        其中QTreeWidget控件虽然是树形结构,但是这个树形结构没有根节点,是从根结点的下一层结点开始计算的(如下图),所以是新增顶层结点

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        QTreeWidget 核⼼信号

        信号说明
        currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* old)切换选中元素时触发
        itemClicked(QTreeWidgetItem* item, int col)点击元素时触发
        itemDoubleClicked(QTreeWidgetItem* item, int col)双击元素时触发
        itemEntered(QTreeWidgetItem* item, int col)⿏标进⼊时触发
        itemExpanded(QTreeWidgetItem* item)元素被展开时触发
        itemCollapsend(QTreeWidgetItem* item)元素被折叠时触发

        QTreeWidgetItem 核⼼属性

        属性说明
        text持有的⽂本
        textAlignment⽂本对⻬⽅式
        icon持有的图表
        font⽂本字体
        hidden是否隐藏
        disabled是否禁⽤
        expand是否展开
        sizeHint尺⼨⼤⼩
        selected是否选中

        QTreeWidgetItem 核⼼⽅法(子节点的方法)

        ⽅法说明
        addChild(QTreeWidgetItem* child)新增⼦节点
        childCount()⼦节点的个数
        child(int index)获取指定下标的⼦节点. 返回 QTreeWidgetItem*
        takeChild(int index)删除对应下标的⼦节点
        removeChild(QTreeWidgetItem* child)删除对应的⼦节点
        parent()获取该元素的⽗节点

        实操:理解顶层元素和子元素的添加删除

        通过界面编辑快速填充初始值

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        代码操作:

        1. 拖拽一个treeWidget
        2. 设置根节点的名字 setHeaderLabel
        3. 新增顶层结点
          1. 创建 QTreeWidgetItem 结点对象
          2. 每个结点都可以设置多个列名称 setText(列数(从0开始),名称猫、狗、鸟)
          3. 添加到顶层结点中,addTopLevelItem
        4. 再添加猫的子节点
          1. 写创建 结点对象,设置名称(列数,中华田园猫、布偶猫、…)
          2. 添加到item1中的子节点 addChild

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        三个按钮的槽函数

        1. 插入顶层结点按钮添加点击信号的槽函数
          1. 获取输入框中的内容
          2. 构造一个节点对象,设置名称 setText 将获取到的内容给到
          3. 添加到顶层结点中
        2. 插入子节点
          1. 获取当前选中节点对象 currentItem(若为空则啥也不做返回…)
          2. 获取输入框中的内容
          3. 构造一个节点对象,
          4. 设置名称 setText 将获取到的内容给到(同上12不变)
          5. 插入到选中结点的子节点中
        3. 删除选中的元素
          1. 获取选中元素
          2. 非空则删除选中元素,需要先获取父元素,通过父元素进行删除 parent
          3. 若为空则代表为顶层元素
            1. 获取顶层元素下标 indexOfTopLevelItem
            2. 从控件中删除顶层结点,takeTopLevelItem
          4. 非空则为普通元素,则通过获取的获取的parent删除子结点 removeChild

        结果:

        【C++ Qt】多元素控件(ListWidget、TableWidget、TreeWidget)

        #include "widget.h"
        #include "ui_widget.h"
        #include 
        Widget::Widget(QWidget *parent)
            : QWidget(parent)
            , ui(new Ui::Widget)
        {
            ui->setupUi(this);
            //设置根节点名称
            ui->treeWidget->setHeaderLabel("1");
            //创建结点对象
            QTreeWidgetItem* item1 = new QTreeWidgetItem();
            item1->setText(0,"猫");
            ui->treeWidget->addTopLevelItem(item1);
            //给顶层元素添加子元素
             QTreeWidgetItem* citem1 = new QTreeWidgetItem();
             citem1->setText(0,"狸花猫");
             item1->addChild(citem1);
             //就不多添加了...
            QTreeWidgetItem* item2 = new QTreeWidgetItem();
            item2->setText(0, "狗");
            ui->treeWidget->addTopLevelItem(item2);
            QTreeWidgetItem* item3 = new QTreeWidgetItem();
            item3->setText(0, "⻦");
            ui->treeWidget->addTopLevelItem(item3);
        }
        Widget::~Widget()
        {
            delete ui;
        }
        //添加顶层元素
        void Widget::on_pushButton_clicked()
        {
            //获取输入框内容
            QString text = ui->lineEdit->text();
            if(text == QString()){
                text = "默认值...";
            }
            //将内容创建项目
            QTreeWidgetItem* item = new QTreeWidgetItem();
            item->setText(0,text);
            //添加到顶层
            ui->treeWidget->addTopLevelItem(item);
        }
        //添加选中的子元素
        void Widget::on_pushButton_2_clicked()
        {
            //获取当前选中的顶层元素
            QTreeWidgetItem* item = ui->treeWidget->currentItem();
            if(item == nullptr) return ;
            //获取输入框内容
            QString text = ui->lineEdit->text();
            if(text == QString()){
                text = "默认值...";
            }
            //将输入框内容添加到创建的新子元素中
            QTreeWidgetItem* citem = new QTreeWidgetItem();
            citem->setText(0,text);
            //给顶层添加新元素
            item->addChild(citem);
        }
        //删除选中的节点
        void Widget::on_pushButton_3_clicked()
        {
            //获取当前选中的节点
             QTreeWidgetItem* item = ui->treeWidget->currentItem();
             //需要获取父元素,通过父元素进行删除
             QTreeWidgetItem* pitem = item->parent();
             //若为空则,此时已经是顶层元素
             if(pitem == nullptr){
                 //获取指定节点的顶层元素的下标
                 int index = ui->treeWidget->indexOfTopLevelItem(item);
                 ui->treeWidget->takeTopLevelItem(index);
             }
             else{ //若不是则:
                 //通过获取的父元素,删除指定的子元素
                 pitem->removeChild(item);
             }
        }
        

        注意上述控件相关的操作,数据都是在内存中的,重新运行程序数据就没了


        本章完。预知后事如何,暂听下回分解。

        如果有任何问题欢迎讨论哈!

        如果觉得这篇文章对你有所帮助的话点点赞吧!

        持续更新大量C++细致内容,早关注不迷路。

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码