5.多元素控件
Qt中提供的多元素控件有:
QListWidget QListView QTablewidget QTableview QTreewidget QTreeview
xxWidget和xView之间的区别
以QTableWidget和QTableView为例.
- QTableView是基于MVC设计的控件.QTableView自身不持有数据.使用QTableView的时候需要用户创建一个Model对象(比如QStandardModel),并且把Model和QTableView关联起来.后续修改Mode中的数据就会影响QTableView的显示;修改QTableView的显示也会影响到Model中的数据(双向绑定).
 - QTableWidget则是QTableview的子类,对Model进行了封装.不需要用户手动创建Model对象,直接就可以往QTableWidget中添加数据了
 
①List Widget 纵向列表
|   属性  |   说明  | 
|   currentRow  |   当前被选中的是第几行  | 
|   count  |   一共有多少行  | 
|   sortingEnable  |   是否允许排序  | 
|   isWrapping  |   是否允许换行  | 
|   itemAlignment  |   元素的对齐方式  | 
|   selectRectVisible  |   被选中的元素矩形是否可见  | 
|   spacing  |   元素之间的间隔  | 
核心方法
|   方法  |   说明  | 
|   addItem(const QString& label) addItem(QListWidgetItem* item)  |   列表中添加元素.  | 
|   currentItem()  |   返回  | 
|   setCurrentItem(QListWidgetItem* item)  |   设置选中第几行元素  | 
|   setCurrentRow(int row)  |   在指定的位置插入元素  | 
|   insertItem(const QString& label,int row) insertItem(QListWidgetItem *item,int row)  |   在指定的位置插入元素  | 
|   item(int row)  |   返回  | 
|   takeItem(int row)  |   删除指定行的元素,返回QListWidgetltem*表示是哪个元素被删除了  | 
核心信号
|   方法  |   说明  | 
|   currentltemChanged(QListWidgetltem* current,QListWidgetltem* old)  |   选中不同元素时会触发.参数是当前选中的元素和之前选中的元素.  | 
|   currentRowChanged(int)  |   选中不同元素时会触发.参数是当前选中元素的行数,  | 
|   itemclicked(QListWidgetltem* item)  |   点击某个元素时触发  | 
|   itemDoubleClicked(QListWidgetltem* item)  |   双击某个元素时触发  | 
|   itemEntered(QListWidgetltem* item)  |   鼠标进入元素时触发  | 
在上述介绍中,涉及到一个关键的类,QListwidgetItem
这个类表示QListWidget中的一个元素
核心方法如下,本质上就是一个"文本+图标"构成的
|   方法  |   说明  | 
|   setFont  |   设置字体  | 
|   setIcon  |   设置图标  | 
|   setHidden  |   设置隐藏  | 
|   setSizeHint  |   设置尺寸  | 
|   setSelected  |   设置是否选中  | 
|   setText  |   设置文本  | 
|   setTextAlignment  |   设置文本对齐方式  | 
①使用ListWidget

#include "widget.h"
#include "ui_widget.h"
# include<QDebug>
#include <QListWidgetItem>
//  注意加头文件,在头文件中也要加
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->listWidget->addItem("C++");
    ui->listWidget->addItem("Java");
    ui->listWidget->addItem("Python");
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_listWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
     if(current != NULL && previous != NULL)
     {
         qDebug() << "当前选中:" << current->text()
                  << "之前选中:" << previous->text();
     }
}
void Widget::on_pushButton_create_clicked()
{
    //获取到输入框内的内容
    const QString& text = ui->lineEdit->text();
    if(text.isEmpty())
    {
        return;
    }
    ui->listWidget->addItem(text);
}
void Widget::on_pushButton_delete_clicked()
{
    //获取当前被选中的元素
    int row = ui->listWidget->currentRow();
    //删除这一行
    ui->listWidget->takeItem(row);
}
 
②Table Widget 表格控件
使用QTablewidget表示一个表格控件,一个表格中包含若干行,每一行又包含若干列,表格中的每个单元格,是一个QTableWidgetItem对象
核心方法
|   方法  |   说明  | 
|   item(int row,int column)  |   根据行数列数获取指定的 
  | 
|   setltem(int row,int column,QTableWidget*)  |   根据行数列数设置表格中的元素  | 
|   currentltem()  |   返回被选中的元素QTableWidgetltem*  | 
|   currentRow()  |   返回被选中元素是第几行  | 
|   currentColumn()  |   返回被选中元素是第几列  | 
|   row(QTableWidgetltem*)  |   获取指定item是第几行  | 
|   column(QTableWidgetltem*)  |   获取指定item是第几列  | 
|   rowCount()  |   获取行数  | 
|   columnCount()  |   获取列数  | 
|   insertRow(int row)  |   在第roW行处插入新行  | 
|   insertColumn(int column)  |   在第column列插入新列  | 
|   removeRow(int row)  |   删除第row行  | 
|   removeColumn(int column)  |   删除第column列  | 
|   setHorizontalHeaderltem(int column,QTableWidget*)  |   设置指定列的表头  | 
|   setVerticalHeaderltem(int row, QTableWidget*)  |   设置指定行的表头  | 
核心信号
|   信号  |   说明  | 
|   cellClicked (int row,int column)  |   点击单元格时触发  | 
|   cellDoubleClicked(int row,int column)  |   双击单元格时触发  | 
|   cellEntered(int row,int column)  |   鼠标进入单元格时触发  | 
|   currentCellChanged(int row,int column,int previousRow,int previousColumn)  |   选中不同单元格时触发  | 
核心方法
|   方法  |   说明  | 
|   row()  |   获取当前是第几行  | 
|   column()  |   获取当前是第几列  | 
|   setText(const QString&)  |   设置文本  | 
|   setTextAlignment(int)  |   设置文本对齐  | 
|   setlcon(const Qlcon&)  |   设置图标  | 
|   setSelected(bool)  |   设置被选中  | 
|   setSizeHints(const QSize&)  |   设置尺寸  | 
|   setFont(const QFont&)  |   设置字体  | 
①使用QTableWidget

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建三行
    ui->tableWidget->insertRow(0);
    ui->tableWidget->insertRow(1);
    ui->tableWidget->insertRow(2);
    //创建三列
    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("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("21"));
    ui->tableWidget->setItem(2,0,new QTableWidgetItem("1003"));
    ui->tableWidget->setItem(2,1,new QTableWidgetItem("王五"));
    ui->tableWidget->setItem(2,2,new QTableWidgetItem("19"));
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_addrow_clicked()
{
    int rowcount = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(rowcount);
}
void Widget::on_pushButton_addcolumn_clicked()
{
    int colcount = ui->tableWidget->columnCount();
    ui->tableWidget->insertColumn(colcount);
    //设置列名
    const QString& name = ui->lineEdit->text();
    ui->tableWidget->setHorizontalHeaderItem(colcount,new QTableWidgetItem(name));
}
void Widget::on_pushButton_deleterow_clicked()
{
    int rowcount = ui->tableWidget->currentRow();
    ui->tableWidget->removeRow(rowcount);
}
void Widget::on_pushButton_deletecolumn_clicked()
{
    int curcol = ui->tableWidget->currentColumn();
    ui->tableWidget->removeColumn(curcol);
}
 
默认情况下,单元格中的内容直接就是可编辑的
如果不想让用户编辑,可以设置
ui->tablewidget>setEditTriggers(QAbstractItemView:NoEditTriggers);
③Tree Widget 树形控件
使用QTreewidget表示一个树形控件.里面的每个元素,都是一个QTreeWidgetItem,每个QTreewidgetItem可以包含多个文本和图标,每个文本/图标为一个列
可以给QTreewidget设置顶层节点(顶层节点可以有多个),然后再给顶层节点添加子节点,从而构成树形结构.
核心方法
|   方法  |   说明  | 
|   clear  |   清空所有子节点  | 
|   addTopLevelltem(QTreeWidgetltem* item)  |   新增顶层节点  | 
|   topLevelltem(int index)  |   获取指定下标的顶层节点,  | 
|   topLevelltemCount()  |   获取顶层节点个数  | 
|   indexOfTopLevelltem(QTreeWidgetltem* item)  |   查询指定节点是顶层节点中的下标  | 
|   takeTopLevelltem(int index)  |   删除指定的顶层节点.返回QTreeWidgetltem*表示被删除 的元素  | 
|   currentltem()  |   获取到当前选中的节点,返回QTreeWidgetltem*  | 
|   setCurrentltem(QTreeWidgetltem*item)  |   选中指定节点  | 
|   setExpanded(bool)  |   展开/关闭节点  | 
|   setHeaderLabel(const QString& text)  |   设置TreeWidget的header名称.  | 
核心信号
|   信号  |   说明  | 
|   currentltemChanged(QTreeWidgetltem* current,QTreeWidgetltem*old)  |   切换选中元素时触发  | 
|   itemClicked(QTreeWidgetltem*item,int col)  |   点击元素时触发  | 
|   itemDoubleClicked(QTreeWidgetltem*item, int col)  |   双击元素时触发  | 
|   itemEntered(QTreeWidgetltem*item,int col)  |   鼠标进入时触发  | 
|   itemExpanded(QTreeWidgetltem*item)  |   元素被展开时触发  | 
|   itemCollapsend(QTreeWidgetltem*item)  |   元素被折叠时触发  | 
核心属性
|   属性  |   说明  | 
|   text  |   持有的文本  | 
|   textAlignment  |   文本对齐方式  | 
|   icon  |   持有的图表  | 
|   font  |   文本字体  | 
|   hidden  |   是否隐藏  | 
|   disabled  |   是否禁用  | 
|   expand  |   是否展开  | 
|   sizeHint  |   尺寸大小  | 
|   selected  |   是否选中  | 
核心方法
|   方法  |   说明  | 
|   addChild(QTreeWidgetltem* child)  |   新增子节点  | 
|   childCount()  |   子节点的个数  | 
|   child(int index)  |   获取指定下标的子节点.返回QTreeWidgetltem'  | 
|   takeChild(int index)  |   删除对应下标的子节点  | 
|   removeChild(QTreeWidgetltem* child)  |   删除对应的子节点  | 
|   parent()  |   获取该元素的父节点  | 
①使用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);
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_addtop_clicked()
{
    //获取输入框内容
    const QString& text = ui->lineEdit->text();
    if(text.isEmpty())
    {
        return;
    }
    QTreeWidgetItem* item = new QTreeWidgetItem();
    item->setText(0,text);
    ui->treeWidget->addTopLevelItem(item);
}
void Widget::on_pushButton_addclick_clicked()
{
    //获取输入框内容
    const QString& text = ui->lineEdit->text();
    if(text.isEmpty())
    {
        return;
    }
    //获取当前选中节点
    QTreeWidgetItem* currentitem = ui->treeWidget->currentItem();
    if(currentitem == NULL)
    {
        return;
    }
    //构造新的item
    QTreeWidgetItem* newitem = new QTreeWidgetItem();
    newitem->setText(0,text);
    //添加item到新节点
    currentitem->addChild(newitem);
    //展开父节点
    currentitem->setExpanded(true);
}
void Widget::on_pushButton_delect_clicked()
{
    QTreeWidgetItem* currentitem = ui->treeWidget->currentItem();
    if(currentitem == NULL)
    {
        return;
    }
    //获取当前节点的父节点
    QTreeWidgetItem* parent = currentitem->parent();
    if(parent==NULL)
    {
        //顶层节点
        int index = ui->treeWidget->indexOfTopLevelItem(currentitem);
        ui->treeWidget->takeTopLevelItem(index);
    }
    else
    {
        //非顶层节点
        parent->removeChild(currentitem);
    }
}
 
- QTreeWidgetItem* currentitem = ui->treeWidget->currentItem(); 这行代码获取当前在树形控件中选中的节点(QTreeWidgetItem),如果没有任何节点被选中,currentItem() 将返回NULL。
 - if(currentitem == NULL) { return; } 如果currentitem是NULL,表示没有选中任何节点,所以直接结束函数的执行。
 - QTreeWidgetItem* parent = currentitem->parent(); 获取当前选中节点的父节点。
 - if(parent == NULL) { ... } 如果父节点是NULL,表示当前选中的节点是一个顶层节点(即它没有父节点)。
 - int index = ui->treeWidget->indexOfTopLevelItem(currentitem); 获取顶层节点在树形控件中的索引。
 - ui->treeWidget->takeTopLevelItem(index); 使用索引从树形控件中移除顶层节点,takeTopLevelItem函数会删除节点并返回它,允许开发者重新使用或删除这个节点。
 - else { ... } 如果当前节点不是顶层节点,执行else块中的代码。
 - parent->removeChild(currentitem); 调用父节点的removeChild函数来删除当前选中的子节点。
 






![[Linux]基本指令(二)](https://i-blog.csdnimg.cn/direct/40a28bba84f546a4b9addfa77a545019.png)










