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和controller都帮我们实现好了,拿过来就可以直接使用,还提供了功能很方便的api

List  Widget

使用QListWidget能够显示一个纵向的列表

QListWidget属性

currentRow:当前被选中的是第几行

count:一共有多少行

sortingEnabled:是否允许排序

isWrapping:是否允许换行

itemAlignment:元素的对齐方式

selectRectVisible:被选中的元素矩形是否可见(上图显示的蓝色高亮)

spacing:元素之间的间隔

核心方法

addItem(const  QString&  label)

addItem(QListWidgetItem *item)

这两个都是添加列表中的元素(上图所示的一行),哪为什么会有两个呢

列表中的 每个元素/每一项 就称为一个 Item,更具体的说,就是通过 QListWidgetItem 类表示的。提供两个函数,那么我们既可以直接传QString,也可以传上边类的指针

currentItem():返回 QListWidgetItem * 表示当前选中的元素

setCurrentItem(QListWidgetItem*  item) :设置选择哪个元素

setCurrentRow(int  row):设置选中第几行的元素

insertItem(const  QString&  label,int   row)

insertItem(QListWidgetItem *item,int  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)

鼠标进入元素时触发

QListWidgetItem

之前提到了QListWidgetItem这个类这个类表示 QListWidget 中的一个元素

核心方法如下,本质上就是一个"文本+图标"构成的

setFont:设置字体

setIcon:设置图标

setHidden:设置隐藏

setSizeHint:设置尺寸

 setSelected:设置是否选中

setText:设置文本

setTextAlignment:设置文本对齐方式

QListWidget 的使用

用ListWidget实现对一个列表的增添的删除

在设计页面先拖拽一个listwidget过来

如果拖拽成listview也没事,可以直接右键变型为listwidget

再新增一个lineedit和两个按钮,lineedit用来输入元素,按钮用来增添和删除

在构造函数中为listwidget添加元素

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->listWidget->addItem("abcdef");
    ui->listWidget->addItem(new QListWidgetItem("123456"));
    ui->listWidget->addItem("zxcvbnnm");
    
}

也可以直接右键ListWidget,选中编辑项目,然后直接新增/删除元素

完成两个按钮的slot函数

void Widget::on_pushButton_push_clicked()
{
    //获取label中的内容
    const QString& text = ui->lineEdit->text();
    //把获取到的内容插入到ListWidget中
    ui->listWidget->addItem(text);
}


void Widget::on_pushButton_delete_clicked()
{
    //先获取被选中的元素是哪个
    int row = ui->listWidget->currentRow();
    if(row < 0)
    {
        return;
    }
    ui->listWidget->takeItem(row);
}

再试试信号currentItemChanged

void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    if(current != nullptr)
    {
        qDebug()<<"当前选中的元素是:"<<current->text();
    }
    if(previous != nullptr)
    {
        qDebug()<<"上一个选中的元素是:"<<previous->text();
    }
}

Table Widget

使用QTableWidget表示一个表格的控件。一个表格中包含若干行,每行中包含若干列。

表格中的每个单元格,都表示一个 QTableWidgetItem 对象

QTableWidget方法

QTableWidget的核心方法

item(int  row,int  column):根据行数列数获取指定的QTableWidgetItem*

setItem(int row,int column,QTableWidget*)

根据行数列数设置表格中的元素

currentItem():返回被选中的元素QTableWidgetItem*

currentRow():返回被选中的元素是第几行

currentColumn():返回被选中的元素是第几列

row(QTableWidgetItem*):获取指定Item是第几行

column(QTableWidgetItem* ):获取指定Item是第几列

rowCount():获取行数

columnCount()获取列数

insertRow(int row)在第row行处插入新行

insertColumn(int column) 在第column列插入新列

removeRow(int row):删除第row行

removeColumn(int column):删除第column列

setHorizontalHeaderItem(int column,QTableWidget*):设置指定列的表头

setVerticalHeaderItem(int row,QTableWidget* ):设置指定行的表头

QTableWidgetItem

QTableWidgetItem单元格的核心信号

cellClicked(int row,int column):

点击单元格时触发

cellDoubleClicked(int row,int column):

双击单元格时触发

cellEntered(int row,int column):

鼠标进入单元格时触发

currentCellChanged(int row,int column,int previousRow,int previousColumn):

选中不同单元格时触发

QTableWidgetItem核心方法

row():获取当前是第几行

column():获取当前是第几列

setText(const QString&):设置文本

setTextAlignment(int):设置文本对齐

setIcon(const QIcon&): 设置图标

setSelected(bool): 设置被选中

setSizeHints(const QSize&): 设置尺寸

setFont(const QFont&) :设置字体

QTableWidget的使用

在界面上创建QTableWidget 和4个按钮,一个输入框

编写widget.cpp构造函数,构造表格中的初始数据(也可以通过图形化界面操作:右键编辑项目——新增行、列。如果当前表格的数据是固定的,那么就可以通过图形化界面编辑,但是实际开发中很多时候数据是由文件、网络来加载的,此时通过图形化编辑就不合适了)

创建3行

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

创建3列

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

设置列名

 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("20250101"));
    ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
    ui->tableWidget->setItem(0,2,new QTableWidgetItem("21"));
    
    ui->tableWidget->setItem(1,0,new QTableWidgetItem("20250102"));
    ui->tableWidget->setItem(1,1,new QTableWidgetItem("李四"));
    ui->tableWidget->setItem(1,2,new QTableWidgetItem("23"));
    
    ui->tableWidget->setItem(2,0,new QTableWidgetItem("20250103"));
    ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2,2,new QTableWidgetItem("20"));

运行完是这样的

还有4个按钮的slot函数没有完成

void Widget::on_pushButton_insertrow_clicked()
{
    //需要知道当前有多少行(然后再插入新行)
    int row_count = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row_count);
}

void Widget::on_pushButton_insertcolumn_clicked()
{
    //需要知道当前有多少列
    int Column_count = ui->tableWidget->columnCount();
    ui->tableWidget->insertColumn(Column_count);
    //设置列名(从lineEdit获取)
    const QString& text = ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(Column_count,new QTableWidgetItem(text));
}

void Widget::on_pushButton_deleterow_clicked()
{
    //获取当前选中行
    int curRow = ui->tableWidget->currentRow();
    //删除选中行
    ui->tableWidget->removeRow(curRow);
}



void Widget::on_pushButton_deletecolumn_clicked()
{
    //获取当前选中列
    int curColumn = ui->tableWidget->currentColumn();
    //删除
    ui->tableWidget->removeColumn(curColumn);
}

代码

#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("20250101"));
    ui->tableWidget->setItem(0,1,new QTableWidgetItem("张三"));
    ui->tableWidget->setItem(0,2,new QTableWidgetItem("21"));

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

    ui->tableWidget->setItem(2,0,new QTableWidgetItem("20250103"));
    ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2,2,new QTableWidgetItem("20"));

}

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


void Widget::on_pushButton_insertrow_clicked()
{
    //需要知道当前有多少行(然后再插入新行)
    int row_count = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(row_count);
}

void Widget::on_pushButton_insertcolumn_clicked()
{
    //需要知道当前有多少列
    int Column_count = ui->tableWidget->columnCount();
    ui->tableWidget->insertColumn(Column_count);
    //设置列名(从lineEdit获取)
    const QString& text = ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(Column_count,new QTableWidgetItem(text));
}

void Widget::on_pushButton_deleterow_clicked()
{
    //获取当前选中行
    int curRow = ui->tableWidget->currentRow();
    //删除选中行
    ui->tableWidget->removeRow(curRow);
}



void Widget::on_pushButton_deletecolumn_clicked()
{
    //获取当前选中列
    int curColumn = ui->tableWidget->currentColumn();
    //删除
    ui->tableWidget->removeColumn(curColumn);
}

Tree  Widget

使用QTreeWidget 表示一个树形控件。里边的每个元素,都是⼀个QTreeWidgetItem ,每个 QTreeWidgetItem 可以包含多个文本和图标,每个文本/图标为一个列。

可以给QTreeWidget 设置顶层节点(顶层节点可以有多个,也就是此树形结构异于其他树形结构——没有根节点,从根节点下一层节点(顶层节点)开始),然后再给顶层节点添加子节点,从而构成树形结构。

QTreeWidget属性

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核心信号

currentItemChanged(QTreeWidgetItem* current,QTreeWidgetItem* old)

        切换选中元素时触发

itemClicked(QTreeWidgetItem*item,intcol)

        点击元素时触发

itemDoubleClicked(QTreeWidgetItem* item, int col)

        双击元素时触发

itemEntered(QTreeWidgetItem* item,int col)

        鼠标进入时触发

itemExpanded(QTreeWidgetItem* item)

        元素被展开时触发

itemCollapsend(QTreeWidgetItem* item)

        元素被折叠时触发

上边都是关于顶层节点的那么如何进行子节点的创建呢?

QTreeWidgetItem

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(), 获取该元素的父节点

QTreeWidget的使用

界面创建一个QTreeWidget和一个lineEdit以及3个pushButton按钮。

初始化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* item1c1 = new QTreeWidgetItem();
    QTreeWidgetItem* item1c2 = new QTreeWidgetItem();
    QTreeWidgetItem* item1c3 = new QTreeWidgetItem();
    item1c1->setText(0,"橘猫");
    item1c2->setText(0,"狸花猫");
    item1c3->setText(0,"布偶猫");
    item1->addChild(item1c1);
    item1->addChild(item1c2);
    item1->addChild(item1c3);

    //狗的子节点
    QTreeWidgetItem* item2c1 = new QTreeWidgetItem();
    QTreeWidgetItem* item2c2 = new QTreeWidgetItem();
    item2c1->setText(0,"中华田园犬");
    item2c2->setText(0,"哈士奇");
    item2->addChild(item2c1);
    item2->addChild(item2c2);

}

然后就是完成我们的三个按钮的槽函数

//添加顶层元素slot函数
void Widget::on_pushButton_insertTopLevelItem_clicked()
{
    //获取输入框的内容
    const QString& text = ui->lineEdit->text();

    //构造一个Item
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0,text);//把输入框的内容录入item
    ui->treeWidget->addTopLevelItem(item);//添加到顶层节点

}
//添加到选中元素的slot函数
void Widget::on_pushButton_insertItem_clicked()
{
    //获取当前选中的元素
    QTreeWidgetItem* itemf = ui->treeWidget->currentItem();
    if(itemf == nullptr)
    {
        return;
    }
    //获取输入框的内容(新增节点的名字)
    const QString& text = ui->lineEdit->text();

    //构造一个 item
    QTreeWidgetItem* itemc = new QTreeWidgetItem();
    itemc->setText(0,text);


    //把新增元素添加到当前选中元素中
    itemf->addChild(itemc);

}

void Widget::on_pushButton_deleteItem_clicked()
{
    //获取当前选中的元素
    QTreeWidgetItem* itemcurr = ui->treeWidget->currentItem();
    if(itemcurr == nullptr)
    {
        return;
    }
    //获取当前节点的父节点,如果父节点是空,那么就要调用顶层节点的函数删除(不是的话就用父节点来删除当前节点)
    QTreeWidgetItem* parent = itemcurr->parent();
    if(parent == nullptr)
    {
        //获取顶层节点(被选中的节点)的下标
        int index = ui->treeWidget->indexOfTopLevelItem(itemcurr);
        //删除节点
        ui->treeWidget->takeTopLevelItem(index);
    }
    else
    {
        //调用父节点删除对应的子节点
        parent->removeChild(itemcurr);
    }
}

注意:上述这几个控件相关的操作,数据都是在内存中保存的,无论在界面上进行任何操作,重新运行程序之后,之前的数据就都没了

如果要想让数据能够重启程序还不丢失,那么就需要编写更多的代码把内存中的数据获取到,写入到文件中,并且在程序下一次运行的时候从文件中加载数据

容器类控件

Group Box

使用QGroupBox 实现⼀个带有标题的分组框。可以把其他的控件放到里边作为一组。

注意:

多元素控件,包含的内容是一个一个自定义好的"Item"对象。

容器类控件,包含的内容是前面所学的各种控件放一块

不要把QGroupBox 和 QButtonGroup 混淆

属性

title:分组框的标题

alignment:分组框内部内容的对齐方式

flat: 是否是"扁平"模式

checkable:是否可选择。设为true,则在title前边会多出一个个可勾选的部分。

checked: 描述分组框的选择状态(前提是checkable为true)

使用

给麦当劳案例加上分组框

在界面上拖拽所需控件

总共3组

把flat和checkable勾上看看

Tab  Widget

使用 QTabWidget 实现一个带有标签页的控件,可以往里边添加一些widget。进一步的就可以通过标签页来切换。

属性

tabPosition 标签页所在的位置

        North 上方

        South 下方

        West 左侧

        East 右侧

currentIndex: 当前选中了第几个标签页(从0开始计算)

currentTabText: 当前选中的标签页的文本

currentTabName: 当前选中的标签页的名字

currentTabIcon:当前选中的标签页的图标

currentTabToolTip: 当前选中的标签页的提示信息

tabsCloseable: 标签页是否可以关闭

movable:标签页是否可以移动

核心信号

currentChanged(int):

         在标签页发生切换时触发,参数为被点击的选项卡编号

tabBarClicked(int):

        在点击选项卡的标签条的时候触发。参数为被点击的选项卡编号

tabBarDoubleClicked(int)

在双击选项卡的标签条的时候触发。参数为被点击的选项卡编号

tabCloseRequest(int):

         在标签页关闭时触发。参数为被关闭的选项卡编号

使用

拖拽TabWidget控件

运行后是这样的,可以点击tab1,tab2选项卡进行切换标签页

可以将一些控件放入标签页中,右下角有属性可以更改标签页名称

右键控件还可以进行页的插入和删除,其中3的页3选项中有子选项可以进行删除

Tab Widget的使用

使用标签页管理多组控件

在界面上创建一个QTabWidget ,和两个按钮

编写widget.cpp进行初始化,给标签页中放个简单的label

注意:

新创建的label的父元素,是ui->tab 和 ui->tab_2 。

Qt中使用父子关系决定该控件 "在哪里"

#include "widget.h"
#include "ui_widget.h"
#include <QLabel>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //在每个标签页中添加一个label
    QLabel* label1 = new QLabel(ui->tab);
    label1->setText("标签页1");
    label1->resize(100,50);

    QLabel* label2 = new QLabel(ui->tab_2);
    label2->setText("标签页2");
    label2->resize(100,50);
}

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

实现两个按钮的槽函数以及标签页信号的使用


void Widget::on_pushButton_clicked()
{
    //使用adTab 方法来创建新的标签页——参数1要指定一个Qwidget
    //参数2 指定标签页的标题
    int count = ui->tabWidget->count();//获取标签页的数量
    QWidget* w = new QWidget();
    ui->tabWidget->addTab(w,QString("Tab")+QString::number(count + 1));



    //添加QLabel显示内容
    QLabel* label = new QLabel(w);
    label->setText(QString("标签页")+QString::number(count + 1));
    label->resize(100,50);

    //新增标签页之后自动选中
    ui->tabWidget->setCurrentIndex(count);
}

void Widget::on_pushButton_2_clicked()
{
    //获取选中标签页的下标
    int index = ui->tabWidget->currentIndex();
    
    //删除操作
    ui->tabWidget->removeTab(index);
}
void Widget::on_tabWidget_currentChanged(int index)
{
    qDebug()<<"当前选中的标签页下标是"<<index;
}

更多推荐