04-8_Qt 5.9 C++开发指南_QTableWidget的使用

2023-11-12

1. QTableWidget概述

QTableWidget是Qt中的表格组件类。在窗体上放置一个QTableWidget 组件后,可以在 PropertyEditor 里对其进行属性设置,双击这个组件,可以打开一个编辑器,对其 Colum、Row 和 Item 进行编辑。一个QTableWidget 组件的界面基本结构如图4-17 所示,这个表格设置为6行5列。

在这里插入图片描述

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

除了行表头和列表头之外的表格区域是内容区,内容区是规则的网格状,如同一个二维数组,每个网格单元称为一个单元格。每个单元格有一个行号、列号,图4-17 表示了行号、列号的变化规律。

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

实例 samp4_9以QTableWidget 为主要组件,演示 QTableWidget 一些主要操作的实现。实例运行时的界面如图 4-18 所示,该实例将演示以下功能的实现方法。

  • 设置表格的列数和行数,设置表头的文字、格式等。

  • 初始化表格数据,设置一批实例数据填充到表格里。

  • 插入行、添加行、删除当前行的操作。

  • 遍历表格所有单元格,读取表格内容到一个 QPlainTextEdit 里,表格的一行数据作为一行文本。

  • 表格上选择的当前单元格变化时,在状态栏显示单元格存储的信息

在这里插入图片描述

2. 源码

2.1 可视化UI设计

在这里插入图片描述

2.2 程序框架

在这里插入图片描述

2.3 qwintspindelegate.h

#ifndef QWINTSPINDELEGATE_H
#define QWINTSPINDELEGATE_H

#include    <QObject>
#include    <QWidget>
#include    <QItemDelegate>

class QWIntSpinDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    QWIntSpinDelegate(QObject *parent=0);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const Q_DECL_OVERRIDE;

    void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const Q_DECL_OVERRIDE;
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
                              const QModelIndex &index) const Q_DECL_OVERRIDE;
};

#endif // QWINTSPINDELEGATE_H

2.4 qwintspindelegate.cpp

#include "qwintspindelegate.h"

#include    <QSpinBox>

QWIntSpinDelegate::QWIntSpinDelegate(QObject *parent):QItemDelegate(parent)
{

}

QWidget *QWIntSpinDelegate::createEditor(QWidget *parent,
   const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option);
    Q_UNUSED(index);

    QSpinBox *editor = new QSpinBox(parent);
    editor->setFrame(false);
    editor->setMinimum(0);
    editor->setMaximum(10000);

    return editor;
}

void QWIntSpinDelegate::setEditorData(QWidget *editor,
                      const QModelIndex &index) const
{
    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->setValue(value);
}

void QWIntSpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->interpretText();
    int value = spinBox->value();

    model->setData(index, value, Qt::EditRole);
}

void QWIntSpinDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index);
    editor->setGeometry(option.rect);
}

2.5 mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include    <QMainWindow>
#include    <QLabel>
#include    <QTableWidgetItem>

#include    "qwintspindelegate.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
//  自定义单元格Type的类型,在创建单元格的Item时使用
    enum    CellType{ctName=1000,ctSex,ctBirth,ctNation,ctPartyM,ctScore}; //各单元格的类型

//  各字段在表格中的列号
    enum    FieldColNum{colName=0, colSex,colBirth,colNation,colScore,colPartyM};

    QLabel  *labCellIndex; //状态栏上用于显示单元格的行号、列号
    QLabel  *labCellType;  //状态栏上用于显示单元格的type
    QLabel  *labStudID;    //状态栏上用于显示单元格的data,

    QWIntSpinDelegate   spinDelegate; //代理组件

    void    createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,
                            QString Nation,bool isPM,int score); //为某一行创建items
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_btnSetHeader_clicked();  //设置表头 按键

    void on_btnSetRows_clicked(); //设置行数 按键

    void on_btnIniData_clicked(); //初始化数据 按键

    void on_chkBoxTabEditable_clicked(bool checked); //表格可编辑 checkbox

    void on_chkBoxHeaderH_clicked(bool checked); //显示行表头 checkbox

    void on_chkBoxHeaderV_clicked(bool checked); //显示列表头 checkbox

    void on_chkBoxRowColor_clicked(bool checked); //间隔行底色 checkbox

    void on_rBtnSelectItem_clicked();   // 行选择模式 RadioButton

    void on_rBtnSelectRow_clicked();    // 单元格选择模式 RadioButton

    void on_btnReadToEdit_clicked(); //读取表格内容到文本 按键

    void on_tableInfo_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn);

    void on_btnInsertRow_clicked();  //插入行 按键

    void on_btnAppendRow_clicked(); //添加行  按键

    void on_btnDelCurRow_clicked();     //删除当前行 按键

    void on_btnAutoHeght_clicked();

    void on_btnAutoWidth_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

2.6 mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include    <QDate>
#include    <QTableWidgetItem>
#include    <QComboBox>
#include    <QTextBlock>
#include    <QTextDocument>

void MainWindow::createItemsARow(int rowNo,QString Name,QString Sex,QDate birth,QString Nation,bool isPM,int score)
{ //为一行的单元格创建 Items
    QTableWidgetItem    *item;
    QString str;
    uint StudID=201605000; //学号基数

//姓名
    //新建一个Item,设置单元格type为自定义的MainWindow::ctName
    item=new  QTableWidgetItem(Name,MainWindow::ctName);
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter); //文本对齐格式
    StudID  +=rowNo; //学号=基数+ 行号
    item->setData(Qt::UserRole,QVariant(StudID));  //设置studID为data
    ui->tableInfo->setItem(rowNo,MainWindow::colName,item); //为单元格设置Item

//性别
    QIcon   icon;
    if (Sex=="男")
        icon.addFile(":/images/icons/boy.ico");
    else
        icon.addFile(":/images/icons/girl.ico");
    item=new  QTableWidgetItem(Sex,MainWindow::ctSex); //新建一个Item,设置单元格type为自定义的 MainWindow::ctSex
    item->setIcon(icon);
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//为单元格设置Item
    ui->tableInfo->setItem(rowNo,MainWindow::colSex,item);//为单元格设置Item

//出生日期
    str=birth.toString("yyyy-MM-dd"); //日期转换为字符串
    item=new  QTableWidgetItem(str,MainWindow::ctBirth);//新建一个Item,设置单元格type为自定义的 MainWindow::ctBirth
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter); //文本对齐格式
    ui->tableInfo->setItem(rowNo,MainWindow::colBirth,item);//为单元格设置Item

//民族
    item=new  QTableWidgetItem(Nation,MainWindow::ctNation); //新建一个Item,设置单元格type为自定义的 MainWindow::ctNation
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本对齐格式
    ui->tableInfo->setItem(rowNo,MainWindow::colNation,item);//为单元格设置Item

//是否党员
    item=new  QTableWidgetItem("党员",MainWindow::ctPartyM);//新建一个Item,设置单元格type为自定义的 MainWindow::ctPartyM
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本对齐格式
    if (isPM)
        item->setCheckState(Qt::Checked);
    else
        item->setCheckState(Qt::Unchecked);
    item->setBackgroundColor(Qt::yellow);//Qt::green  lightGray  yellow
    ui->tableInfo->setItem(rowNo,MainWindow::colPartyM,item);//为单元格设置Item

//分数
    str.setNum(score);
    item=new  QTableWidgetItem(str,MainWindow::ctScore);//新建一个Item,设置单元格type为自定义的 MainWindow::ctPartyM
    item->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//文本对齐格式
    ui->tableInfo->setItem(rowNo,MainWindow::colScore,item);//为单元格设置Item
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setCentralWidget(ui->splitterMain);

    //状态栏初始化创建
    labCellIndex = new QLabel("当前单元格坐标:",this);
    labCellIndex->setMinimumWidth(250);

    labCellType=new QLabel("当前单元格类型:",this);
    labCellType->setMinimumWidth(200);

    labStudID=new QLabel("学生ID:",this);
    labStudID->setMinimumWidth(200);

    ui->statusBar->addWidget(labCellIndex);//加到状态栏
    ui->statusBar->addWidget(labCellType);
    ui->statusBar->addWidget(labStudID);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_btnSetHeader_clicked()
{ //设置表头
    QTableWidgetItem    *headerItem;
    QStringList headerText;
    headerText<<"姓 名"<<"性 别"<<"出生日期"<<"民 族"<<"分数"<<"是否党员";  //表头标题用QStringList来表示
//    ui->tableInfo->setHorizontalHeaderLabels(headerText);
    ui->tableInfo->setColumnCount(headerText.count());//列数设置为与 headerText的行数相等
    for (int i=0;i<ui->tableInfo->columnCount();i++)//列编号从0开始
    {
       headerItem=new QTableWidgetItem(headerText.at(i)); //新建一个QTableWidgetItem, headerText.at(i)获取headerText的i行字符串
       QFont font=headerItem->font();//获取原有字体设置
       font.setBold(true);//设置为粗体
       font.setPointSize(12);//字体大小
       headerItem->setTextColor(Qt::red);//字体颜色
       headerItem->setFont(font);//设置字体
       ui->tableInfo->setHorizontalHeaderItem(i,headerItem); //设置表头单元格的Item
    }

    ui->tableInfo->setItemDelegateForColumn(colScore,&spinDelegate);//设置自定义代理组件
}

void MainWindow::on_btnSetRows_clicked()
{ //设置行数,设置的行数为数据区的行数,不含表头
 //如设置10行,数据区有10行,但是访问行号为0~9
    ui->tableInfo->setRowCount(ui->spinRowCount->value());//设置数据区行数
    ui->tableInfo->setAlternatingRowColors(ui->chkBoxRowColor->isChecked()); //设置交替行背景颜色
}

void MainWindow::on_btnIniData_clicked()
{ //初始化表格内容
    QString strName,strSex;
    bool    isParty=false;

    QDate   birth;
    birth.setDate(1980,4,7);//初始化一个日期
    ui->tableInfo->clearContents();//只清除工作区,不清除表头

    int Rows=ui->tableInfo->rowCount(); //数据区行数,
    for (int i=0;i<Rows;i++) //数据区第1行的编号为0,所以范围是0~rowCount()-1
    {
        strName=QString::asprintf("学生%d",i); //学生姓名
        if ((i % 2)==0) //分奇数,偶数行设置性别,及其图标
            strSex="男";
        else
            strSex="女";

        createItemsARow(i, strName, strSex, birth,"汉族",isParty,70); //为某一行创建items

        birth=birth.addDays(20); //日期加20天
        isParty =!isParty;
    }
}

void MainWindow::on_chkBoxTabEditable_clicked(bool checked)
{ //设置编辑模式
    if (checked)
//双击或获取焦点后单击,进入编辑状态
        ui->tableInfo->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
    else
        ui->tableInfo->setEditTriggers(QAbstractItemView::NoEditTriggers); //不允许编辑
}

void MainWindow::on_chkBoxHeaderH_clicked(bool checked)
{//是否显示水平表头
    ui->tableInfo->horizontalHeader()->setVisible(checked);
}

void MainWindow::on_chkBoxHeaderV_clicked(bool checked)
{//是否显示垂直表头
    ui->tableInfo->verticalHeader()->setVisible(checked);
}

void MainWindow::on_chkBoxRowColor_clicked(bool checked)
{ //行的底色交替采用不同颜色
    ui->tableInfo->setAlternatingRowColors(checked);
}

void MainWindow::on_rBtnSelectItem_clicked()
{//选择行为:单元格选择
    ui->tableInfo->setSelectionBehavior(QAbstractItemView::SelectItems);
}

void MainWindow::on_rBtnSelectRow_clicked()
{//选择行为:行选择
    ui->tableInfo->setSelectionBehavior(QAbstractItemView::SelectRows);
}

void MainWindow::on_btnReadToEdit_clicked()
{//将 QTableWidget的所有行的内容提取字符串,显示在QPlainTextEdit里
    QString str;
    QTableWidgetItem    *cellItem;

    ui->textEdit->clear(); //文本编辑器清空
    for (int i=0;i<ui->tableInfo->rowCount();i++) //逐行处理
    {
        str=QString::asprintf("第 %d 行: ",i+1);
       for (int j=0;j<ui->tableInfo->columnCount()-1;j++) //逐列处理,但最后一列是check型,单独处理
        {
            cellItem=ui->tableInfo->item(i,j); //获取单元格的item
            str=str+cellItem->text()+"   "; //字符串连接
        }
       cellItem=ui->tableInfo->item(i,colPartyM);  //最后一列,党员
       if (cellItem->checkState()==Qt::Checked)  //根据check状态显示文字
           str=str+"党员";
       else
           str=str+"群众";
       ui->textEdit->appendPlainText(str); //添加到编辑框作为一行
    }
}

void MainWindow::on_tableInfo_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn)
{//当前选择单元格发生变化时的响应
   Q_UNUSED(previousRow);
   Q_UNUSED(previousColumn);

    QTableWidgetItem* item=ui->tableInfo->item(currentRow,currentColumn); //获取单元格的 Item
    if  (item==NULL)
        return;

    labCellIndex->setText(QString::asprintf("当前单元格坐标:%d 行,%d 列",currentRow,currentColumn));

    int cellType=item->type();//获取单元格的类型
    labCellType->setText(QString::asprintf("当前单元格类型:%d",cellType));

    item=ui->tableInfo->item(currentRow,MainWindow::colName); //取当前行第1列的单元格的 item
    int ID=item->data(Qt::UserRole).toInt();//读取用户自定义数据
    labStudID->setText(QString::asprintf("学生ID:%d",ID));//学生ID
}


void MainWindow::on_btnInsertRow_clicked()
{ //插入一行
    int curRow=ui->tableInfo->currentRow();//当前行号

    ui->tableInfo->insertRow(curRow); //插入一行,但不会自动为单元格创建item
    createItemsARow(curRow, "新学生", "男",
          QDate::fromString("1990-1-1","yyyy-M-d"),"苗族",true,60 ); //为某一行创建items
}

void MainWindow::on_btnAppendRow_clicked()
{ //添加一行
    int curRow=ui->tableInfo->rowCount();//当前行号
    ui->tableInfo->insertRow(curRow);//在表格尾部添加一行
    createItemsARow(curRow, "新生", "女",
          QDate::fromString("2000-1-1","yyyy-M-d"),"满族",false,50 ); //为某一行创建items
}

void MainWindow::on_btnDelCurRow_clicked()
{//删除当前行及其items
    int curRow=ui->tableInfo->currentRow();//当前行号
    ui->tableInfo->removeRow(curRow); //删除当前行及其items
}

void MainWindow::on_btnAutoHeght_clicked()
{
    ui->tableInfo->resizeRowsToContents();
}

void MainWindow::on_btnAutoWidth_clicked()
{
    ui->tableInfo->resizeColumnsToContents();
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

04-8_Qt 5.9 C++开发指南_QTableWidget的使用 的相关文章

随机推荐

  • kafka 应用实战

    一 Java 中使用 kafka 进行通信 依赖
  • 孟岩谈通证(11):通证所代表的多维价值观

    通证Token都有那些多维价值观呢 我还是你举一个特别具体的例子来说明 我有一个朋友他开了一个社区 是专门做中小学教育课外辅导老师之间交流的 社区里大家互相交换教学资料 试题等等材料 你说这个东西有没有价值 教书育人 然后帮助孩子们成长 这
  • ssh远程连接Ubuntu(局域网和非局域网)

    文章目录 前言 1 局域网 远程连接 2 非局域网 远程连接 3 Zerotier常用命令 4 远程桌面控制 总结 前言 我们通常使用ssh连接虚拟机中的Ubuntu 方便学习 但是当在项目中遇到远程控制主机的时候 发现ssh连接不到外网主
  • Vue中实现电子围栏/围栏(高德地图)功能:

    1 思路 大部分与车辆轨迹相同 1 先获取key gt 官网 https lbs amap com ref https console amap com 2 下载并导入依赖 npm install vue amap S 3 使用 2 官网
  • 加速乐-AAencode-ob混淆

    加速乐 AAencode ob混淆 多层响应 Cookie 逆向 前言 本次案例是对加速乐 AAEncode OB 混淆方式的破解 破解出多层响应 Cookie 逆向 声明 本文章中所有内容仅供学习交流 相关链接做了脱敏处理 若有侵权 请联
  • Eclipse安装LomBok插件

    1 使用LomBok的好处在于实体类不用手动去生成set get方法了 类会在编译时自动生成 是代码简洁节省工作量 2 maven项目的pom文件添加坐标下载
  • 程序员进阶架构师的必备——思维导图

    架构师是什么 要做什么 架构师 是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物 架构师不是一个人 他需要建立高效的体系 带领团队去攻城略地 在规定的时间内完成项目 1 确认需求 架构师要懂得用户需求
  • 什么是面向对象思想

    面向对象是一种思想 是基于面向过程而言的 就是说面向对象是将功能等通过对象来实现 将功能封装进对象之中 让对象去实现具体的细节 这种思想是将数据作为第一位 而方法或者说是算法作为其次 这是对数据一种优化 操作起来更加的方便 简化了过程 面向
  • 人工智能作业homework2--------A*算法解决八数码

    1 启发式搜索算法A 启发式搜索算法A 一般简称为A算法 是一种典型的启发式搜索算法 其基本思想是 定义一个评价函数f 对当前的搜索状态进行评估 找出一个最有希望的节点来扩展 评价函数的形式如下 f n g n h n 其中n是被评价的节点
  • 全网最详细中英文ChatGPT接口文档(五)30分钟快速入门ChatGPT——手把手示例教程:如何建立一个人工智能回答关于您的网站问题,小白也可学

    30分钟开始使用ChatGPT Models模型 How to build an AI that can answer questions about your website 如何建立一个人工智能 回答有关您的网站的问题 Getting
  • 整理了27个Python人工智能库,建议收藏

    为了大家能够对人工智能常用的 Python 库有一个初步的了解 以选择能够满足自己需求的库进行学习 对目前较为常见的人工智能库进行简要全面的介绍 1 Numpy NumPy Numerical Python 是 Python的一个扩展程序库
  • ssd m.2接口详解

    ssd有两种接口 一种是sata 一种是m 2 这里主要深入讲解一下m 2接口的ssd 1 ssd 尺寸与规格 我们在买ssd的时候 商家都会说什么ssd是2280还是2242规格的 这里的规格实际上就是代表的ssd的大小 M 2模组的尺寸
  • pytrch手写数字识别

    使用Pytorch实现手写数字识别 目标 知道如何使用Pytorch完成神经网络的构建 知道Pytorch中激活函数的使用方法 知道Pytorch中torchvision transforms中常见图形处理函数的使用 知道如何训练模型和如何
  • Unity:利用 射线Ray 检测物体

    利用 射线Ray 检测物体 Unity射线 Ray 是通过发射一条射线来检测碰撞体或触发器 不带碰撞器组件的物体时无法检测的 可以在物理设置里取消检测触发器 Edit Project Setting Physics Physics2D Ph
  • Spring Boot中的Dozer和MapStruct比较

    Spring Boot中的Dozer和MapStruct比较 在Java开发中 数据对象之间的转换是一个常见的任务 Spring Boot作为一个流行的Java框架 提供了多种方式来处理对象之间的转换 两个常用的工具是Dozer和MapSt
  • call、apply、bind方法详解

    1 每个函数都包含两个非继承而来的方法 call 方法和apply 方法 2 相同点 这两个方法的作用是一样的 只是传参方式不一样而已 call 方法使用 window msg 1 document msg 2 var log msg 3
  • springboot 如何修改控制台输出的图案

    如图 操作步骤 1 在项目的resource文件夹下 新建一个文件命名为banner txt 2 进入网站 http patorjk com software taag p display h 0 v 0 f Big t SpringBoo
  • Spring WebSocket通信应用

    文章目录 前言 一 客户端 服务端双向通信交互图 二 项目说明 1 引入包 2 项目各模块说明 问题 参考 前言 本文章主要记录项目客户端 服务端双向通信解决方案 基于Spring WebSocket架构实现双向数据通信 以及项目实际应用中
  • 【SQLAlchemy】第二篇——连接失效及连接池

    一 背景 为了节约资源 MySQL会对建立的连接进行监控 当某些连接处于不活跃状态的时间超过一个阈值时 则关闭它们 用户可以执行show variables like wait timeout 来查看这个阈值 可以看到 在默认的情况下 这个
  • 04-8_Qt 5.9 C++开发指南_QTableWidget的使用

    文章目录 1 QTableWidget概述 2 源码 2 1 可视化UI设计 2 2 程序框架 2 3 qwintspindelegate h 2 4 qwintspindelegate cpp 2 5 mainwindow h 2 6 m