24、QTableWidget---------常见界面组件类

QTableWidget

QTableWidget是用来以表格方式展现数据的结构

QTableWidget的构造函数

cpp 复制代码
//指定父节点构造QTableWidget
QTableWidget::QTableWidget(QWidget *parent = nullptr)
//指定行号,列号以及父节点构造QTableWidget
QTableWidget::QTableWidget(int rows, int columns, QWidget *parent = nullptr)

示例

cpp 复制代码
//构造一个三行四列的QTableWidget
auto table_wid = new QTableWidget(3,4);

设置表头

设置行数和列数

cpp 复制代码
//设置列数
void setColumnCount(int columns);
//获取列数
int columnCount() const;
//设置行数
void setRowCount(int rows);
//返回行数
int rowCount() const;

示例

cpp 复制代码
auto table_wid = new QTableWidget();
//设置列数为3
table_wid->setColumnCount(3);
//设置行数为3
table_wid->setRowCount(3);

设置水平表头的标签

cpp 复制代码
void QTableWidget::setHorizontalHeaderLabels(const QStringList &labels)

设置垂直表头的标签信息

cpp 复制代码
void QTableWidget::setVerticalHeaderLabels(const QStringList &labels)

示例

cpp 复制代码
auto table_wid = new QTableWidget();
//设置列数为3
table_wid->setColumnCount(3);
//设置行数为3
table_wid->setRowCount(3);
//设置水平标签
table_wid->setHorizontalHeaderLabels(
     QStringList()<<"Column 1" << "Column 2" << "Column 3");
//设置垂直标签
table_wid->setVerticalHeaderLabels(
     QStringList()<<"Row 1" << "Row 2" << "Row 3");

当前项和选中

当前项

QTableWidget有选中和当前项的概念,

当前项是当前选中的列表项,通过视觉效果显示出来,用户可通过键盘或者鼠标与当前项交互, 比如当前项时第一行第一列

有时会没有当前项,可以通过这个函数判断

cpp 复制代码
QTableWidgetItem *currentItem() const;

如果这个函数返回值为空,则说明当前QTableWidget没有焦点。

选中

选中和当前项不同,选中可以选择多个,但是当前项只能有一个。

当我们选中一列或一行的时候,当前项所在的单元格可能就变化了。

大家可以看到当我点击第二列的时候,在第二列第一行出现了虚线框,说明当前项变成了第1行第2列。

示例

cpp 复制代码
//创建3行4列的表格
auto table_wid = new QTableWidget(3,4);
//获取当前item
auto * cur_item = table_wid->currentItem();

设置当前项

我们可以通过setCurrentItem或者setCurrentCell设置当前项

cpp 复制代码
//设置当前项
void QTableWidget::setCurrentItem(QTableWidgetItem *item)
//设置当前项
void QTableWidget::setCurrentCell(int row, int column)
cpp 复制代码
//将当前项设置为第1行第1列
ui->tableWidget->setCurrentCell(0,0);

获取当前的列和行

cpp 复制代码
//返回焦点当前的行
int currentRow() const;
//返回焦点当前的列
int currentColumn() const;

示例

获取当前焦点所在的行号和列号

cpp 复制代码
//创建3行4列的表格
auto table_wid = new QTableWidget(3,4);
//获取当前行
auto cur_row = table_wid->currentRow();
//获取当前列
auto cur_col = table_wid->currentCol();

插入列

我们可以在指定位置插入一列

cpp 复制代码
//在第column插入一列
void QTableWidget::insertColumn(int column)

示例

cpp 复制代码
//创建3行4列的表格
auto table_wid = new QTableWidget(3,3);
//设置水平标签
table_wid->setHorizontalHeaderLabels(
     QStringList()<<"Column 1" << "Column 2" << "Column 3");
//设置垂直标签
table_wid->setVerticalHeaderLabels(
     QStringList()<<"Row 1" << "Row 2" << "Row 3");
//在第二列处插入一列
table_wid->insertColumn(0);

默认情况下,插入的列名字为其所在的列序号,如果想改为我们自定义的名字可调用

cpp 复制代码
void setHorizontalHeaderItem(int column, QTableWidgetItem *item);

第一个参数为要修改的头部的哪一列,第二个参数为用item替换这个头部的列

示例

cpp 复制代码
//创建3行4列的表格
auto table_wid = new QTableWidget(3,3);
//设置水平标签
table_wid->setHorizontalHeaderLabels(
     QStringList()<<"Column 1" << "Column 2" << "Column 3");
//设置垂直标签
table_wid->setVerticalHeaderLabels(
     QStringList()<<"Row 1" << "Row 2" << "Row 3");
//在第二列处插入一列
table_wid->insertColumn(0);    
 //更新列的名字
 auto * col_item = new QTableWidgetItem("Column 0");
 //更新cur_col的列表头
 table_wid->setHorizontalHeaderItem(0, col_item);

删除列

cpp 复制代码
//删除第column列
void removeColumn(int column);

示例

cpp 复制代码
//删除第2列
table_wid->removeColumn(1);

获取列数

cpp 复制代码
//返回tablewidget的列数
int columnCount() const;

行的操作和列类似,这里我们列举下行的用法

cpp 复制代码
//删除行
 void removeRow(int row);
//插入行
 void insertRow(int row);
//设置垂直表头
QTableWidgetItem *takeVerticalHeaderItem(int row);

更新数据

我们可以更新某一行某一列的单元格内的数据

cpp 复制代码
//更新row行(从0开始),column列(从0开始)的单元格数据 
void setItem(int row, int column, QTableWidgetItem *item);

示例

cpp 复制代码
//创建一个item用来填充数据
auto new_item = new QTableWidgetItem("hello");
//将item设置到表格中,更新第2行1列数据
table_wid->setItem(1,0,new_item);

删除数据

通过takeItem根据行和列选择要删除的item

cpp 复制代码
 QTableWidgetItem *takeItem(int row, int column);

调用delete删除这个item即可清空单元格数据

cpp 复制代码
 delete item;

点击信号

QTableWidget中的某个item被点击会发出itemClicked信号

cpp 复制代码
[signal] void QTableWidget::itemClicked(QTableWidgetItem *item)

可以捕获这个信号,对点击的item做一些处理和判断。

注意

QTableWidget中必须有item,点击这个item才会发出itemClicked信号,如果是空的表格是不会发出这个信号的。

对于空表格项或者存储item的表格项,我们可以捕获cellClicked信号

cpp 复制代码
[signal] void QTableWidget::cellClicked(int row, int column)

示例

cpp 复制代码
//创建3行4列的表格
auto table_wid = new QTableWidget(3,3);
//连接单元格被点击的信号
connect(table_wid, &QTableWidget::cellClicked, [](int row, int column){
    qDebug()<< "row is " << row <<" column is " << column;
})

练习案例

实现如下界面

要求

  1. 创建一个3行3列的表格,表头列信息分别为Column 1,Column 2,Column 3...

行信息分别为Row1, Row2, Row3...

  1. 默认为第1行第1列单元格为当前项
  2. 根据输入的信息,点击增加列,将信息增加到当前列之前。支持在最后一列之后追加列,删除列等操作。
  3. 根据输入的信息,点击增加行,将信息增加到当前行之前,支持在最后一行之后追加行,删除行等操作。
  4. 点击选中后,打印当前条目信息。
  5. 支持更新数据和删除数据操作。

答案

先拖动界面ui布局达到如下效果

界面关系图

接下来我们在MainWindow的构造函数中初始化表格

cpp 复制代码
//设置列
ui->tableWidget->setColumnCount(3);
//设置行
ui->tableWidget->setRowCount(3);
//设置水平头部标签
ui->tableWidget->setHorizontalHeaderLabels(
 QStringList()<<"Column 1" << "Column 2" << "Column 3");
//设置垂直头部标签
ui->tableWidget->setVerticalHeaderLabels(
 QStringList()<<"Row 1" << "Row 2" << "Row 3");
//默认设置当前项为第1行第1列
ui->tableWidget->setCurrentCell(0,0);
//初始化焦点信息
qDebug() << ui->tableWidget->currentItem();
auto cur_row = ui->tableWidget->currentRow();
auto cur_col = ui->tableWidget->currentColumn();
qDebug() << cur_row << cur_col;
if(cur_row != -1 && cur_col != -1){
    ui->label_4->setText(
    QString("当前条目: %1行%2列").arg(cur_row).arg(cur_col));
}

构造函数中,响应某个item被点击,只有在表格中有数据的时候点击才会触发。

cpp 复制代码
//响应某个item被点击
connect(ui->tableWidget,&QTableWidget::itemClicked,
        [this](QTableWidgetItem *item){

    ui->label_4->setText( QString("当前条目: %1行%2列").
                          arg(item->row()).arg(item->column()));
});

响应某个单元格被点击

cpp 复制代码
//响应某个单元被点击
connect(ui->tableWidget, &QTableWidget::cellClicked,
        [this](int row, int column){
    ui->label_4->setText( QString("当前条目: %1行%2列").
                          arg(row).arg(column));
       });

响应添加列按钮被点击

cpp 复制代码
//添加列
connect(ui->addCol,&QPushButton::clicked, [this](){
    //判断文本是否为空
    if(ui->lineEdit->text().isEmpty()){
        QMessageBox::information(this,"通知","输入文本为空");
        return;
    }

    //获取当前单元所在的列
    auto cur_col = ui->tableWidget->currentColumn();
    if(cur_col < 0){
        QMessageBox::information(this,"通知","未选中任何列");
        return;
    }

    //在cur_col位置插入一列
    ui->tableWidget->insertColumn(cur_col);
    //要插入的文本
    auto text = ui->lineEdit->text();
    //更新列的名字
    auto * col_item = new QTableWidgetItem(text);
    //更新cur_col的列表头
    ui->tableWidget->setHorizontalHeaderItem(cur_col, col_item);

});

响应追加列被点击

cpp 复制代码
//追加列
connect(ui->appendCol,&QPushButton::clicked,[this](){
    //判断文本是否为空
    if(ui->lineEdit->text().isEmpty()){
        QMessageBox::information(this,"通知","输入文本为空");
        return;
    }

    //获取列号
    auto col_count = ui->tableWidget->columnCount();
    //新增一列数据
    ui->tableWidget->insertColumn(col_count);
    //要插入的文本
    auto text = ui->lineEdit->text();
    //生成一个item用来更新表头数据
    auto col_item = new QTableWidgetItem(text);
    //更新表头对应的列数据
    ui->tableWidget->setHorizontalHeaderItem(col_count, col_item);

});

响应删除列按钮被点击

cpp 复制代码
//删除列
connect(ui->delCol,&QPushButton::clicked,[this](){
    auto col = ui->tableWidget->currentColumn();
    if(col < 0){
        QMessageBox::information(this,"通知","未选中任何列");
        return;
    }

    ui->tableWidget->removeColumn(col);
});

响应添加行按钮被点击

cpp 复制代码
//添加行
connect(ui->addRow,&QPushButton::clicked,[this](){
    //判断是否存在当前选中行
    auto cur_row = ui->tableWidget->currentRow();
    if(cur_row < 0){
        QMessageBox::information(this,"通知","未选中任何行");
        return;
    }

    //获取文本输入框内容
    auto text = ui->lineEdit->text();
    if(text.isEmpty()){
        QMessageBox::information(this,"通知","输入信息为空");
        return;
    }

    //在cur_row插入一行
    ui->tableWidget->insertRow(cur_row);
    //创建一个item用来更新表头的行信息
    auto row_item = new QTableWidgetItem(text);
    ui->tableWidget->setVerticalHeaderItem(cur_row, row_item);
});

响应删除行和追加行的按钮点击信号

cpp 复制代码
//删除行
connect(ui->delRow,&QPushButton::clicked,[this](){
    //获取当前行
    auto cur_row = ui->tableWidget->currentRow();
    ui->tableWidget -> removeRow(cur_row);
});

//追加行
connect(ui->appendRow,&QPushButton::clicked,[this](){

    //判断文本内容
    auto text = ui->lineEdit->text();
    if(text.isEmpty()){
        QMessageBox::information(this,"通知","输入信息为空");
        return;
    }
    //获取总行数
    auto row_count = ui->tableWidget->rowCount();
    //在末尾的行后添加一行
    ui->tableWidget->insertRow(row_count);
    //创建item用来填写表头信息
    auto item = new QTableWidgetItem(text);
    //把item 放入垂直表头里
    ui->tableWidget->setVerticalHeaderItem(row_count,item);
});

添加数据

cpp 复制代码
//添加数据
connect(ui->addData,&QPushButton::clicked,[this](){
    //判断文本内容
    auto text = ui->lineEdit->text();
    if(text.isEmpty()){
        QMessageBox::information(this,"通知","输入信息为空");
        return;
    }
    //获取输入的行号
    auto row_str = ui->rowLineEdit->text();
    //获取输入的列号
    auto col_str = ui->colLineEdit->text();
    if(row_str.isEmpty() || col_str.isEmpty()){
        QMessageBox::information(this,"通知","行号或列号为空");
        return;
    }

    bool b_success = false;
    auto row_int = row_str.toInt(&b_success);
    if(!b_success){
        QMessageBox::information(this,"通知","行号转换失败");
        return;
    }

    auto col_int = col_str.toInt(&b_success);
    if(!b_success){
        QMessageBox::information(this,"通知","列号转换失败");
        return;
    }

    //创建一个item用来填充数据
    auto new_item = new QTableWidgetItem(text);
    //将item设置到表格中
    ui->tableWidget->setItem(row_int-1,col_int-1,new_item);
});

响应删除数据的按钮点击事件

cpp 复制代码
//删除数据
connect(ui->delData, &QPushButton::clicked, [this](){
    //判断文本内容
    auto text = ui->lineEdit->text();
    if(text.isEmpty()){
        QMessageBox::information(this,"通知","输入信息为空");
        return;
    }
    //获取输入的行号
    auto row_str = ui->rowLineEdit->text();
    //获取输入的列号
    auto col_str = ui->colLineEdit->text();
    if(row_str.isEmpty() || col_str.isEmpty()){
        QMessageBox::information(this,"通知","行号或列号为空");
        return;
    }

    bool b_success = false;
    auto row_int = row_str.toInt(&b_success);
    if(!b_success){
        QMessageBox::information(this,"通知","行号转换失败");
        return;
    }

    auto col_int = col_str.toInt(&b_success);
    if(!b_success){
        QMessageBox::information(this,"通知","列号转换失败");
        return;
    }

    //删除指定行列的数据
    auto item = ui->tableWidget->takeItem(row_int-1,col_int-1);
    delete item;
});
相关推荐
咯哦哦哦哦2 小时前
windows下VSCode配置C++/CMake/Qt/MVSC 开发环境 【电脑已经安装vs2022】
c++·vscode·qt
一晌小贪欢2 小时前
PyQt5 + Pandas 打造常见的表格(Excel/CSV)读取与处理工具
python·qt·excel·pandas·python办公·excel处理
爱思考的小伙18 小时前
Qt-02:信号与槽
开发语言·qt
森G19 小时前
22、GUI控件类---------常见界面组件类
qt
森G21 小时前
21、信号和槽详解---------QT基础
qt
西装没钱买21 小时前
QT组播的建立和使用(绑定特定的网卡,绑定特定IP)
网络·c++·qt·udp·udp组播
森G1 天前
20、元对象系统---------QT基础
qt
Laurence1 天前
CMake 报错 Failed to find required Qt component WebEngineWidgets
qt·webengine·cmake·找不到
习惯就好zz1 天前
Qt Quick 系统托盘完整实践
开发语言·qt·qml·系统托盘·system tray·qapplication·qguiapplication