C++ Qt开发:TableWidget表格组件

用户国营  金牌会员 | 2024-2-25 19:41:31 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 883|帖子 883|积分 2649

Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableWidget表格组件的常用方法及灵活运用。
QTableWidget 是 Qt 中用于显示表格数据的部件。它是 QTableView 的子类,提供了一个简单的接口,适用于一些不需要使用自定义数据模型的简单表格场景。该组件可以看作是TreeWidget树形组件的高级版,表格组件相比于树结构组件灵活性更高,不仅提供了输出展示二维表格功能,还可以直接对表格元素直接进行编辑与修改操作,表格结构分为表头,表中数据两部分,表格结构可看作一个二维数组,通过数组行列即可锁定特定元素。
以下是 QTableWidget 类的一些常用方法的简要说明:
方法描述setItem(int row, int column, QTableWidgetItem *item)设置指定行和列的项item(int row, int column) const返回指定行和列的项setRowCount(int rows)设置表格的行数setColumnCount(int columns)设置表格的列数rowCount() const返回表格的行数columnCount() const返回表格的列数setHorizontalHeaderLabels(const QStringList &labels)设置水平表头的标签setVerticalHeaderLabels(const QStringList &labels)设置垂直表头的标签setItemPrototype(QTableWidgetItem *item)设置原型项,用于在新插入的单元格中创建副本insertRow(int row)在指定行插入新行removeRow(int row)移除指定行insertColumn(int column)在指定列插入新列removeColumn(int column)移除指定列clear()清空表格的所有内容clearContents()清空表格的所有单元格的内容,但保留表头和行列数itemAt(int x, int y) const返回给定坐标下的项setCurrentItem(QTableWidgetItem *item)设置当前项,用于指定当前被选择的项currentItem() const返回当前被选择的项setCurrentCell(int row, int column)设置当前单元格,用于指定当前被选择的单元格currentRow() const返回当前被选择的行号currentColumn() const返回当前被选择的列号setItemDelegate(QAbstractItemDelegate *delegate)设置项代理,用于自定义单元格的显示和编辑方式setSortingEnabled(bool enable)启用或禁用排序功能sortItems(int column, Qt::SortOrder order)对指定列进行排序setEditTriggers(EditTriggers triggers)设置触发编辑的事件editItem(QTableWidgetItem *item)编辑指定项的内容openPersistentEditor(QTableWidgetItem *item)打开指定项的持久编辑器closePersistentEditor(QTableWidgetItem *item)关闭指定项的持久编辑器itemChanged(QTableWidgetItem *item)当项的内容发生变化时发出的信号cellClicked(int row, int column)单元格被单击时发出的信号cellDoubleClicked(int row, int column)单元格被双击时发出的信号这些方法提供了对 QTableWidget 的基本操作和配置的途径。使用这些方法,你可以动态地调整表格的大小、内容,设置表头,进行排序,处理编辑触发事件等。
首先我们准备好UI界面部分,该界面包含的元素较为复杂,如果找不到这些组件可以参考文章底部的完整案例代码;

1.1 设置初始表格

如下代码演示了如何使用 QTableWidget 设置表头。
以下是关于该代码的一些解释:

  • setHorizontalHeaderLabels 方法用于设置水平表头的标签。在这里,headerText_Row 是一个包含列标签的字符串列表,每个字符串对应一个表格列。
  • 如果需要设置垂直表头,可以使用 setVerticalHeaderLabels 方法,将一个包含行标签的字符串列表传递给它。
  • 可以通过循环设置表头的每个单元格的属性。在这里,使用了循环遍历列并创建一个 QTableWidgetItem,设置其字体为粗体、字体大小为8,字体颜色为黑色,然后将其设置为相应列的水平表头项。
这样,通过设置表头的不同属性,可以使表格更具可读性和美观性。
  1. // 设置表头的实现
  2. void MainWindow::on_pushButton_clicked()
  3. {
  4.     QTableWidgetItem *headerItem;
  5.     QStringList headerText_Row,headerText_Col;
  6.     headerText_Row << "姓 名" << "性 别" << "出生日期" << "民 族" << "分数" << "是否党员";
  7.     //headerText_Col << "第一行" << "第二行";
  8.     // 设置为水平表头
  9.     ui->tableWidget->setHorizontalHeaderLabels(headerText_Row);
  10.     // 设置垂直表头
  11.     //ui->tableWidget->setVerticalHeaderLabels(headerText_Col);
  12.     // 另一种方式: 通过循环设置
  13.     ui->tableWidget->setColumnCount(headerText_Row.count());       // 列数设置为与headerText_Row的列相等
  14.     for (int i=0;i<ui->tableWidget->columnCount();i++)             // 列编号从0开始
  15.     {
  16.        headerItem=new QTableWidgetItem(headerText_Row.at(i));      // headerText.at(i) 获取headerText的i行字符串
  17.        QFont font=headerItem->font();                              // 获取原有字体设置
  18.        font.setBold(true);                                         // 设置为粗体
  19.        font.setPointSize(8);                                       // 设置字体大小
  20.        headerItem->setTextColor(Qt::black);                        // 设置字体颜色
  21.        headerItem->setFont(font);                                  // 设置字体
  22.        ui->tableWidget->setHorizontalHeaderItem(i,headerItem);     // 设置表头单元格的Item
  23.     }
  24. }
复制代码
如下代码演示了如何从 QSpinBox 中读取数量,并将其设置为 QTableWidget 表格的行数。
以下是关于该代码的一些解释:

  • 通过 ui->spinBox->value() 读取 QSpinBox 中的值,即用户选择的数量。
  • 使用 setRowCount 方法将读取到的数量设置为表格的行数。
  • setAlternatingRowColors(true) 用于交替设置行的底色,以提高可读性。此方法在交替的行之间使用不同的颜色。
通过这样的操作,可以动态地设置表格的行数,以适应用户的需求。
  1. // 从spinBox中读出数量,并设置TableWidget表格的行数
  2. void MainWindow::on_pushButton_2_clicked()
  3. {
  4.     // 读取出spinBox中的数据,并将其设置到表格中
  5.     ui->tableWidget->setRowCount(ui->spinBox->value());
  6.     // 行的底色交替采用不同颜色
  7.     ui->tableWidget->setAlternatingRowColors(true);
  8. }
复制代码
运行程序,分别点击设置表头与设置行数,此时读者会看到如下图所示的输出效果,Table表格被初始化了。

1.1 初始化表格

如下代码中的createItemsARow函数,用于为表格的一行创建各个单元格的 QTableWidgetItem。
以下是对该代码的一些解释:

  • 姓名(Name):

    • 使用 QTableWidgetItem 创建一个单元格,并将其类型设置为自定义的 MainWindow::ctName。
    • 设置文本对齐格式为水平居中和垂直居中。
    • 使用 setData 方法将学号(StudID)设置为单元格的数据。
    • 将 QTableWidgetItem 添加到表格的指定位置。

  • 性别(Sex):

    • 使用 QTableWidgetItem 创建一个单元格,并将其类型设置为自定义的 MainWindow::ctSex。
    • 根据性别设置对应的图标。
    • 设置文本对齐格式为水平居中和垂直居中。
    • 将 QTableWidgetItem 添加到表格的指定位置。

  • 出生日期(birth):

    • 使用 QTableWidgetItem 创建一个单元格,并将其类型设置为自定义的 MainWindow::ctBirth。
    • 将日期转换为字符串,并设置为单元格的文本。
    • 设置文本对齐格式为左对齐和垂直居中。
    • 将 QTableWidgetItem 添加到表格的指定位置。

  • 民族(Nation):

    • 使用 QTableWidgetItem 创建一个单元格,并将其类型设置为自定义的 MainWindow::ctNation。
    • 设置文本对齐格式为水平居中和垂直居中。
    • 将 QTableWidgetItem 添加到表格的指定位置。

  • 是否党员(isPM):

    • 使用 QTableWidgetItem 创建一个单元格,并将其类型设置为自定义的 MainWindow::ctPartyM。
    • 根据是否党员设置对应的复选框状态。
    • 设置文本对齐格式为水平居中和垂直居中。
    • 设置背景颜色为黄色。
    • 将 QTableWidgetItem 添加到表格的指定位置。

  • 分数(score):

    • 使用 QTableWidgetItem 创建一个单元格,并将其类型设置为自定义的 MainWindow::ctScore。
    • 将分数转换为字符串,并设置为单元格的文本。
    • 设置文本对齐格式为水平居中和垂直居中。
    • 将 QTableWidgetItem 添加到表格的指定位置。

通过这样的操作,可以在表格中动态地创建一行,并设置每个单元格的内容和样式。
  1. // 为一行的单元格创建Items行
  2. void MainWindow::createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score)
  3. {
  4.     QTableWidgetItem *item;
  5.     QString str;
  6.     uint StudID=1001;
  7.     // -------------------------------------------------------
  8.     // 姓名
  9.     // -------------------------------------------------------
  10.     // 新建一个Item 设置单元格type为自定义的MainWindow::ctName
  11.     item=new QTableWidgetItem(Name,MainWindow::ctName);
  12.     // 文本对齐格式
  13.     item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  14.     // 学号 = 基数+ 行号
  15.     StudID  +=rowNo;
  16.     // 设置studID为data
  17.     item->setData(Qt::UserRole,QVariant(StudID));
  18.     // 为单元格设置Item
  19.     ui->tableWidget->setItem(rowNo,MainWindow::colName,item);
  20.     // -------------------------------------------------------
  21.     // 性别
  22.     // -------------------------------------------------------
  23.     QIcon icon;
  24.     if (Sex=="男")
  25.     {
  26.         icon.addFile(":/image/boy.ico");
  27.     }
  28.     else
  29.     {
  30.         icon.addFile(":/image/girl.ico");
  31.     }
  32.     // 新建一个Item 设置单元格type为自定义的 MainWindow::ctSex
  33.     item=new  QTableWidgetItem(Sex,MainWindow::ctSex);
  34.     item->setIcon(icon);
  35.     // 为单元格设置Item
  36.     item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  37.     // 为单元格设置Item
  38.     ui->tableWidget->setItem(rowNo,MainWindow::colSex,item);
  39.     // -------------------------------------------------------
  40.     // 出生日期
  41.     // -------------------------------------------------------
  42.     // 日期转换为字符串
  43.     str=birth.toString("yyyy-MM-dd");
  44.     // 新建一个Item 设置单元格type为自定义的 MainWindow::ctBirth
  45.     item=new  QTableWidgetItem(str,MainWindow::ctBirth);
  46.     // 文本对齐格式
  47.     item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
  48.     // 为单元格设置Item
  49.     ui->tableWidget->setItem(rowNo,MainWindow::colBirth,item);
  50.     // -------------------------------------------------------
  51.     // 民族
  52.     // -------------------------------------------------------
  53.     // 新建一个Item 设置单元格type为自定义的 MainWindow::ctNation
  54.     item=new  QTableWidgetItem(Nation,MainWindow::ctNation);
  55.     // 文本对齐格式
  56.     item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  57.     // 为单元格设置Item
  58.     ui->tableWidget->setItem(rowNo,MainWindow::colNation,item);
  59.     // -------------------------------------------------------
  60.     // 是否党员
  61.     // -------------------------------------------------------
  62.     // 新建一个Item 设置单元格type为自定义的 MainWindow::ctPartyM
  63.     item=new  QTableWidgetItem("群众",MainWindow::ctPartyM);
  64.     // 文本对齐格式
  65.     item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  66.     if (isPM)
  67.     {
  68.         item->setCheckState(Qt::Checked);
  69.     }
  70.     else
  71.     {
  72.         item->setCheckState(Qt::Unchecked);
  73.     }
  74.     // 设置为黄色
  75.     item->setBackgroundColor(Qt::yellow);
  76.     // 为单元格设置Item
  77.     ui->tableWidget->setItem(rowNo,MainWindow::colPartyM,item);
  78.     // -------------------------------------------------------
  79.     // 分数
  80.     // -------------------------------------------------------
  81.     str.setNum(score);
  82.     //新建一个Item 设置单元格type为自定义的 MainWindow::ctPartyM
  83.     item=new  QTableWidgetItem(str,MainWindow::ctScore);
  84.     // 文本对齐格式
  85.     item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  86.     // 为单元格设置Item
  87.     ui->tableWidget->setItem(rowNo,MainWindow::colScore,item);
  88. }
复制代码
接着我们来看一下如何实现初始化一个表格的,首先我们需要设置好需要填充的数据,当有了这些数据以后直接调用createItemsARow函数,并传入数据,至此就可以实现创建一行,通过循环的方式则可以实现多行的创建。
如下代码用于初始化表格元素,通过循环为每一行添加学生数据。
以下是代码的主要解释:

  • 清除内容:

    • 使用 ui->tableWidget->clearContents() 清除工作区中的内容,但不清除表格结构。

  • 循环添加行数据:

    • 获取表格的总行数,即数据区的行数。
    • 使用循环为每一行添加学生数据。
    • 使用 QString::asprintf 格式化字符串设置学生姓名。
    • 根据行号的奇偶性设置性别,同时设置对应的图标。
    • 调用 createItemsARow 方法为某一行创建各个单元格的 QTableWidgetItem。

  • 日期处理:

    • 初始日期设定为1997年10月7日。
    • 循环中,每次添加行后,将日期加20天。

  • 党员标志处理:

    • 使用布尔变量 isParty 表示学生是否为党员,每次取反。
    • 将党员标志设置为对应的复选框状态。

通过这样的初始化,表格会被填充上预设的学生数据,每一行包含姓名、性别、出生日期、民族、是否党员和分数等信息。
  1. // 初始化表格元素
  2. void MainWindow::on_pushButton_4_clicked()
  3. {
  4.     QString strName,strSex;
  5.     bool isParty=false;
  6.     QDate birth;
  7.     birth.setDate(1997,10,7);                // 初始化一个日期
  8.     ui->tableWidget->clearContents();        // 只清除工作区中的内容,不清除表格
  9.     int Rows=ui->tableWidget->rowCount();    // 数据区行数
  10.     // 循环添加行数据
  11.     for (int i=0;i<Rows;i++)
  12.     {
  13.         strName=QString::asprintf("学生%d",i);   // 学生姓名
  14.         if ((i % 2)==0)                         // 分奇数,偶数行设置性别,及其图标
  15.             strSex="男";
  16.         else
  17.             strSex="女";
  18.         // 为某一行创建items
  19.         createItemsARow(i, strName, strSex, birth,"汉族",isParty,70);
  20.         // 日期加20天
  21.         birth=birth.addDays(20);
  22.         isParty =!isParty;
  23.     }
  24. }
复制代码
当读者点击将表格读入文本框后则可实现表格转文本,如下图所示;

完整案例下载

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户国营

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表