常见界面设计组件————QTableWidget的使用

QTableWidget概述

QTableWidget是Qt中的表格组件类。在窗体上放置一个QTableWidget组件后,可以在Property Editor里对其属性进行编辑,双击这个组件,可以打开一个编辑器,对其Colum、Row和Item进行编辑。一个QTableWidget的基本结构如图所示:

表格的第一行通常称为表头,用于设置每一列的标题, 第一列称为列表头,可以设置其标题,但一般使用缺省的标题(行号)。行表头和列表头一般不可编辑

除了行表头和列表头之外为表格的内容区,内容区是规则的网格状,每个网格被称为单元格且每个单元格都有行号和列号

在QTableWidget表格中,每个表格都是一个QTableWidgetItem对象,可以设置文字内容、字体、前景色和背景色、图标,也可以设置编辑和显示标记。每个单元格还可以存储一个QVariant数据,用以设置用户自定义数据

实例效果如下:

该实例将演示以下功能的实现:

  • 设置表格的行号和列号,设置表头的文字、格式
  • 初始化表格数据,设置一批实例数据填充到表格中
  • 插入行、添加行、删除当前行等操作
  • 遍历表格所有单元格,读取内容到QPlainTextEdit里,表格的一行数据作为一行文本
  • 表格上选择的当前单元格变化时,在装态栏显示储存的信息

界面的设计于初始化

实例的主窗体从QMainWindow继承而来,窗口中,左侧是一个GroupBox组件,所有的PushButton组件和CheckBox组件都在其中,并且采用栅格布局;右侧分别是一个QTableWidget组件和一个QPlainTextEdit组件,二者采用垂直布局,这是一个典型的三区分割的布局

在主窗体类中,MainWindow里自定义了一些变量和函数,用于后面的代码是实现,下面是在MainWindow的private部分的变量和函数:

private:
    Ui::MainWindow *ui;
    
    //自定义单元格Type的类型,在创建单元格的item时使用
    enum CellType{ctName=1000, ctSex, ctBirth, ctNation, ctPartyM, ctScore};
    //各字段在表格中的列号
    enum FieldColNumP{colName=0, colSex, colBirth, colNation, colPartyM, colScore};
    
    QLabel *labCellIndex;          //状态栏上用以显示单元格的行号、列号
    QLabel *labCellType;           //状态栏上用以显示单元格的type
    QLabel *labStudID;             //状态栏上用以显示学号
    
    //创建item
    void createItemARow(int rowNo, QString Name, QString Sex, QDate brith, 
                        QString Nation, bool isPM, int socore);

枚举类型CellType是用来表示单元格类型的,在创建单元格时使用

枚举类型FieldColNum用枚举常量表示格字段在表格中的列号

QTableWidget操作

设置表头

界面上的"设置表头"按钮实现对表头的设置,其clicked()信号的槽函数代码如下:

void MainWindow::on_btn_SetHeader_clicked()
{
    //设置表头
    QTableWidgetItem *headerItem;
    QStringList headerText;
    headerText<<"姓名"<<"性别"<<"出生日期"<<"民族"<<"分数"<<"是否党员";
    
    //ui->tableWidget->setHorizontalHeaderLabels(headerText);
    ui->tableWidget->setColumnCount(headerText.count());
    for (int i=0; i<ui->tableWidget->columnCount(); i++) {
        headerItem = new QTableWidgetItem(headerText.at(i));
        QFont font = headerItem->font();
        font.setBold(true);     //设置字体加粗
        font.setPointSize(12);  //设置字体字号
        headerItem->setTextColor(Qt::red); //设置颜色
        headerItem->setFont(font);
        ui->tableWidget->setHorizontalHeaderItem(i,headerItem);
    }
}

行表头各列的文字标题由一个QStrnigList对象headerText初始化储存,如果只是设置行表头各列的标题,只需使用:

ui->tableWidget->setHorizontalHeaderLabels(headerText);

如果需要进行更加具体的设置,需要为行表头的每个单元创建一个QTableWidgetItem类型的变量,并进行相关设置

在一个表格中,不管是表头还是工作区,每个单元格都是一个QTableWidgetItem对象。QTableWidgetItem对象储存了单元格的所有内容,包括字标题、格式设置,已经关联的数据。

上面的程序中的for循环遍历headerText的每一行,用每一行的文字创建一个QTableWidgetItem对象headerItem,然后设置headerItem的字体大小,粗体,颜色,然后将headerItem赋给表头的某一列:

ui->tableWidget->setHorizontalHeaderItem(i,headerItem);

初始化列表数据

界面上的"初始化表格数据"按钮根据表格的行数,生成数据填充表格,并为每个单元格生成QTableWidgetItem对象,设置相应属性。下面是btn_IniTable的响应槽函数代码:

void MainWindow::on_btn_InitTable_clicked()
{
    //初始化表格
    QString strName,strSex;
    bool isSingal = true;
    QDate birth;
    birth.setDate(1998,05,01);
    
    ui->tableWidget->clearContents();        //清除工作区,但不清除表头
    int Rows = ui->tableWidget->rowCount();  //数据区行数
    for (int i=0; i<Rows; i++) {
        strName = QString::asprintf("学生%d",i);
        if(i % 2 == 0)                       //按行数的奇偶设置学生不同属性
            strSex = "男";
        else
            strSex = "女";
        
        createItemARow(i, strName, strSex, birth, "汉族",isSingal, 70);
        birth = birth.addDays(20);          //出生日期加20天
        isSingal = !isSingal;
    }
}

其中,QTableWidget::clearContents()函数清除表格工作区的数据,但不会清除表头;QTableWidget::rowCount()函数返回表格的行数

在for循环中为每一行生成需要显示的数据,然后调用自定义函数createItemsARow(),为表格一行的各个单元格生成QTableWidgetItem对象,其详细代码如下:

void MainWindow::createItemARow(int rowNo, QString Name, QString Sex,
                    QDate brith, QString Nation, bool isPM, int score)
{
    //为一行表格创建item
    QTableWidgetItem *item;
    QString str;
    uint StudID = 20190000;                 //学号基数
    item = new QTableWidgetItem(Name,MainWindow::ctName);
    StudID += rowNo;                        //学号=基数+行号
    //姓名
    item->setData(Qt::UserRole,QVariant(StudID));
    ui->tableWidget->setItem(rowNo,MainWindow::colName,item);

    QIcon icon;
    if(Sex == "男")
        icon.addFile("../images/男生.png");
    else
        icon.addFile("../images/女生.png");

    item = new QTableWidgetItem(Sex,MainWindow::ctSex);
    item->setIcon(icon);
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    ui->tableWidget->setItem(rowNo,MainWindow::colSex,item);
    //出生日期
    str = brith.toString("yyyy-MM-dd");           //日期转换为字符串
    item = new QTableWidgetItem(str,MainWindow::ctBirth);
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    ui->tableWidget->setItem(rowNo,MainWindow::colBirth,item);
    //民族
    item = new QTableWidgetItem(Nation,MainWindow::ctNation);
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    ui->tableWidget->setItem(rowNo,MainWindow::colNation,item);
    //是否党员
    item = new QTableWidgetItem("党员",MainWindow::ctPartyM);
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    if(isPM)
        item->setCheckState(Qt::Checked);
    else
        item->setCheckState(Qt::Unchecked);
    item->setBackgroundColor(Qt::yellow);
    ui->tableWidget->setItem(rowNo,MainWindow::colPartyM,item);
    //分数
    str.setNum(score);
    item = new QTableWidgetItem(str,MainWindow::ctScore);
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    ui->tableWidget->setItem(rowNo,MainWindow::colScore,item);
}

该表格的每一行有5列,为每一个单元格都创建一个QTableWidgetItem类型的变量item,并做相应的设置

创建QTableWidgeItem使用的构造函数的原型为:

QTableWidgetItem::QTableWidgetItem(const QString &text, int type = Type)

其中,第一个参数作为单元格的显示文字,第二个参数作为节点的类型;例如创建"姓名"单元格对象时语句是:

item = new QTableWidgetItem(Name,MainWindow::ctName);

其中,MainWindow::ctName是定义枚举类型的一个常量值

"姓名"单元格还调用了setData()函数设置了一个自定义类型数据,储存的信息为学生ID

item->setData(Qt::UserRole,QVariant(StudID));

这个自定义数据是不显示在界面上的,但是与单元格相关联

QTableWidgetItem中有一些函数可以对单元格的属性进行设置,如下:

setTextAlignment(int alignment);        //设置文字对齐方式
setBackground(const QBrush &brush);     //设置单元格背景颜色
setForeground(const QBrush &brush);     //设置单元格前景色
setIcon(const QIcon &icon);             //设置单元格图标
setFont(const QFont &font);             //设置字体
setCheckState(Qt::CheckState state);    //设置单元格勾选状态
setFlages(Qt::ItemFlags flags);         //设置单元格的属性标记

设置完相关属性之后,用QTableWidget的setItem函数将item设置为单元格的项:例如:

ui->tablewidget->setItem(rowNo,MainWindow::colName,item);

其中,MainWindow::colName是定义的枚举类型FiledColNum的一个常量值

当进行初始化之后,表格里面并没有显示学号,学号是"姓名"单元格的关联数据

获取单元格数据

当鼠标在单元格上单击单元格时,被选中的单元格是当前单元格。通过QTableWidget的currentColumn()和currentRow()可以获得当前单元格的列编号和行编号

当前单元格发生切换时,会发射currentCellChanged()信号和currentItemChanged()信号,两个信号的区别在于传递的参数不同

对currentCellChanged()信号编写槽函数,用于获取当前单元格的数据,以及当前行的学生的学号信息

在currentCellChanged()信号中,传递的参数为为当前单元格的行号和列号,通过这两个编号就能得到单元格的QTableWidget对象item

获得item之后,通过type()函数得到单元格的类型参数,这个类型就是创建单元格的QTableWidgetItem对象时传递的类型参数

再获取同一行的"姓名"单元格的项,用data()函数提取自定义数据学生ID

插入、删除、添加行

QTableWidget处理行操作的函数如下:

insertRow(int row):在行号为row的行前面添加一行,如果row等于或大于总行数,则在表格最后添加一行;insertRow()只是添加一个空行,不会为单元格创建QWidgetItem对象,需要手动创建

removeRow(int row):删除行号为row的行

下面是界面上"插入行"、"添加行"、"删除当前行"的响应槽函数。在调用插入之后,会调用createItemARow()函数为新创建的空行的各单元构造QTableWidgetItem对象

void MainWindow::on_btn_InsertItem_clicked()
{
    //插入行
    int curRow = ui->tableWidget->currentRow();
    ui->tableWidget->insertRow(curRow);         //插入空行
    createItemARow(curRow,"新同学","男",QDate::fromString("1990-1-1","yyyy-M-d"),"汉族",true,70);
}

void MainWindow::on_btn_addItem_clicked()
{
    //添加行
    int curRow = ui->tableWidget->rowCount();
    ui->tableWidget->insertRow(curRow);
    createItemARow(curRow,"新同学","女",QDate::fromString("2000-1-1","yyyy-M-d"),"满族",false,70);
}

void MainWindow::on_btn_removeItem_clicked()
{
    //删除行
    int curRow = ui->tableWidget->currentRow();
    ui->tableWidget->removeRow(curRow);
}

自动调整行高和列宽

QTableWIdget有几个函数自动调整表格的行高和列宽,分别如下:

resizeCloumnsToContents()                //自动调整所有列的宽度,以适应其内容
resizeCloumnToContents(int column)      //自动调整列号为column的列的宽度
resizeRowsToContents()                   //自动调整所有行的高度,以适应其内容
resizeRowToContents(int row)            //自动调整行号为row的行的高度

界面中的调整高度和调整宽度的响应槽函数如下:

void MainWindow::on_btn_autoHight_clicked()
{
    //自动调整高度
    ui->tableWidget->resizeRowsToContents();
}

void MainWindow::on_btn_autoWidth_clicked()
{
    //自动调整宽度
    ui->tableWidget->resizeColumnsToContents();
}

读取表格数据

"读取文本"按钮演示了将表格中的数据区的内容全部读出的方法,它将每个单元格的文字读出,同一行的单元格的文字用空格隔开,作为文本的一行,然后将这些文本作为文本编辑器的一行内容,代码如下:

void MainWindow::on_btn_readTable_clicked()
{
    //读取表格数据
    QString str;
    QTableWidgetItem *cellitem;
    ui->plainTextEdit->clear();
    for (int i=0;i<ui->tableWidget->rowCount(); i++) {
        str = QString::asprintf("第%d行:",i+1);
        for (int j=0; j<ui->tableWidget->columnCount()-1; j++) {
            cellitem = ui->tableWidget->item(i,j);
            str = str+cellitem->text()+" ";         //字符串的拼接
        }
        cellitem = ui->tableWidget->item(i,colPartyM);  //最后一列
        if(cellitem->checkState() == Qt::Checked)
            str = str+"党员";
        else {
            str = str+"群众";
        }
        ui->plainTextEdit->appendPlainText(str);
    }
}

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值