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;
});
相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能14 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G14 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt