【Qt | QTableWidget】QTableWidget 类的详细解析与代码实践

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你------泰戈尔🍭
⏰发布时间⏰:

本文未经允许,不得转发!!!

目录

  • [🎄一、QTableWidget 概述](#🎄一、QTableWidget 概述)
    • [✨1.1 什么是 QTableWidget?](#✨1.1 什么是 QTableWidget?)
    • [✨ 1.2 QTableWidget 类层次结构](#✨ 1.2 QTableWidget 类层次结构)
    • [✨ 1.3 开发环境配置](#✨ 1.3 开发环境配置)
  • [🎄二、QTableWidget 的基本使用](#🎄二、QTableWidget 的基本使用)
    • [✨ 2.1 创建表格控件](#✨ 2.1 创建表格控件)
    • [✨ 2.2 设置表格属性](#✨ 2.2 设置表格属性)
  • [🎄三、QTableWidget 常用方法详解](#🎄三、QTableWidget 常用方法详解)
    • [✨ 3.1 数据操作方法](#✨ 3.1 数据操作方法)
      • [🌟3.1.1 设置和获取单元格数据](#🌟3.1.1 设置和获取单元格数据)
      • [🌟3.1.2 批量操作数据](#🌟3.1.2 批量操作数据)
    • [✨ 3.2 外观和样式方法](#✨ 3.2 外观和样式方法)
      • [🌟3.2.1 设置行列属性](#🌟3.2.1 设置行列属性)
      • [🌟3.2.2 单元格样式控制](#🌟3.2.2 单元格样式控制)
    • [✨ 3.3 排序和查找方法](#✨ 3.3 排序和查找方法)
    • [✨ 3.4 信号和槽机制](#✨ 3.4 信号和槽机制)
  • 🎄四、完整例子代码:学生信息管理系统
    • [✨ 4.1 项目结构](#✨ 4.1 项目结构)
    • [✨ 4.2 项目代码](#✨ 4.2 项目代码)
    • [✨ 4.3 运行效果与功能说明](#✨ 4.3 运行效果与功能说明)
  • 🎄五、总结


🎄一、QTableWidget 概述

本文代码开发环境介绍:

系统:win10

Qt开发环境:Qt5.12.12

✨1.1 什么是 QTableWidget?

QTableWidget 是 Qt Widgets 模块中的一个表格控件类,它继承自 QTableView,为开发者提供了一个基于项(item)的模型视图架构。与更通用的 QTableView 相比,QTableWidget 将模型和视图结合在一起,使用起来更加简单直接。

核心特点:

  • 内置数据存储模型(QTableWidgetItem)
  • 支持单元格级别的编辑和选择
  • 提供行列头、单元格样式的高度自定义能力
  • 包含丰富的信号槽机制,便于交互响应

✨ 1.2 QTableWidget 类层次结构

复制代码
QObject
 └── QWidget
      └── QFrame
           └── QAbstractScrollArea
        		└── QAbstractItemView
            	     └── QTableView
                          └── QTableWidget

✨ 1.3 开发环境配置

在 .pro 项目文件中添加必要的模块:

qmake 复制代码
QT += core gui widgets

🎄二、QTableWidget 的基本使用

✨ 2.1 创建表格控件

创建表格涉及到的成员函数有:

cpp 复制代码
// 构造函数
QTableWidget::QTableWidget(QWidget *parent = nullptr)
QTableWidget::QTableWidget(int rows, int columns, QWidget *parent = nullptr)

// 设置行数
void QTableWidget::setRowCount(int rows);

// 设置列数
void QTableWidget::setColumnCount(int columns)

创建 QTableWidget 的基本方式一般有两种:

cpp 复制代码
// 方式1:在代码中直接创建
QTableWidget *tableWidget = new QTableWidget(this);
tableWidget->setRowCount(20);      // 设置20行
tableWidget->setColumnCount(10);   // 设置10列

// 方式2:在UI设计器中拖放添加
// 在Qt Designer中拖放"Table Widget"到窗体
// 然后在代码中通过ui指针访问
ui->tableWidget->setRowCount(20);
ui->tableWidget->setColumnCount(10);

✨ 2.2 设置表格属性

  • 设置表格基本属性的函数继承自 QAbstractItemView 类,相关枚举值可以到 Qt assistant 去查询。

  • 设置横向、纵向标题

    cpp 复制代码
    // 设置横向标题
    void QTableWidget::setHorizontalHeaderLabels(const QStringList &labels)
    // 设置纵向标题
    void QTableWidget::setVerticalHeaderLabels(const QStringList &labels)
  • 设置列宽、行高:horizontalHeader、verticalHeader 继承自 QTableView 类;

  • 设置交替行颜色:setAlternatingRowColors继承自 QAbstractItemView 类;

🌰举例子:

cpp 复制代码
// 设置表格基本属性
tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked); // 双击编辑
tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); // 单选模式
tableWidget->setSelectionBehavior(QAbstractItemView::SelectItems); // 选择单元格

// 设置行列标题
tableWidget->setHorizontalHeaderLabels(QStringList() << "学号" << "姓名" << "性别" 
                                                     << "年龄" << "专业" << "班级" 
                                                     << "语文" << "数学" << "英语" << "总分");
tableWidget->setVerticalHeaderLabels(QStringList()); // 清空行标题

// 设置列宽
tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 自动拉伸
tableWidget->verticalHeader()->setDefaultSectionSize(30); // 设置行高

// 设置交替行颜色(提高可读性)
tableWidget->setAlternatingRowColors(true);
tableWidget->setStyleSheet("alternate-background-color: #f0f0f0; background-color: white;");

🎄三、QTableWidget 常用方法详解

✨ 3.1 数据操作方法

🌟3.1.1 设置和获取单元格数据

cpp 复制代码
// 创建并设置单元格项
QTableWidgetItem *item = new QTableWidgetItem("张三");
item->setTextAlignment(Qt::AlignCenter); // 居中对齐
item->setForeground(QBrush(Qt::blue));   // 设置文字颜色
item->setFont(QFont("Microsoft YaHei", 10)); // 设置字体
tableWidget->setItem(0, 1, item); // 第0行第1列

// 获取单元格数据
QTableWidgetItem *nameItem = tableWidget->item(0, 1);
if (nameItem) {
    QString name = nameItem->text(); // 获取文本
    QColor color = nameItem->foreground().color(); // 获取文字颜色
}

// 设置复选框
QTableWidgetItem *checkItem = new QTableWidgetItem();
checkItem->setCheckState(Qt::Unchecked); // 设置未选中状态
checkItem->setFlags(checkItem->flags() | Qt::ItemIsUserCheckable); // 允许用户勾选
tableWidget->setItem(0, 0, checkItem);

🌟3.1.2 批量操作数据

cpp 复制代码
// 批量插入行
tableWidget->insertRow(0); // 在第一行前插入新行
tableWidget->insertRow(tableWidget->rowCount()); // 在末尾添加新行

// 批量删除行
tableWidget->removeRow(0); // 删除第一行

// 清空所有数据(保留行列结构)
tableWidget->clearContents();

// 清空所有(包括行列结构)
tableWidget->clear();

// 获取选中行
QList<QTableWidgetItem*> selectedItems = tableWidget->selectedItems();
foreach (QTableWidgetItem *item, selectedItems) {
    qDebug() << "选中项:" << item->text() << "行:" << item->row() << "列:" << item->column();
}

✨ 3.2 外观和样式方法

🌟3.2.1 设置行列属性

cpp 复制代码
// 设置列宽
tableWidget->setColumnWidth(0, 80);   // 第0列宽80像素
tableWidget->setColumnWidth(1, 100);  // 第1列宽100像素
tableWidget->horizontalHeader()->setStretchLastSection(true); // 最后一列拉伸

// 设置行高
tableWidget->setRowHeight(0, 40); // 第0行高40像素

// 隐藏行列
tableWidget->hideColumn(9); // 隐藏第9列(总分)
tableWidget->hideRow(5);    // 隐藏第5行

// 显示行列
tableWidget->showColumn(9);
tableWidget->showRow(5);

// 设置行列标题
QStringList horizontalHeaders;
for (int i = 1; i <= 10; ++i) {
    horizontalHeaders << QString("列%1").arg(i);
}
tableWidget->setHorizontalHeaderLabels(horizontalHeaders);

🌟3.2.2 单元格样式控制

cpp 复制代码
// 设置表头样式
QHeaderView *header = tableWidget->horizontalHeader();
header->setStyleSheet("QHeaderView::section {"
                      "background-color: #4CAF50;"
                      "color: white;"
                      "padding: 5px;"
                      "border: 1px solid #ddd;"
                      "font-weight: bold;}");

// 设置特定单元格背景色
for (int row = 0; row < tableWidget->rowCount(); ++row) {
    for (int col = 6; col <= 8; ++col) { // 成绩列
        QTableWidgetItem *item = tableWidget->item(row, col);
        if (item) {
            int score = item->text().toInt();
            if (score >= 90) {
                item->setBackground(QBrush(QColor("#C8E6C9"))); // 绿色背景
            } else if (score >= 60) {
                item->setBackground(QBrush(QColor("#FFF9C4"))); // 黄色背景
            } else {
                item->setBackground(QBrush(QColor("#FFCDD2"))); // 红色背景
            }
        }
    }
}

✨ 3.3 排序和查找方法

cpp 复制代码
// 启用排序
tableWidget->setSortingEnabled(true);

// 按特定列排序(降序)
tableWidget->sortByColumn(9, Qt::DescendingOrder); // 按总分降序排序

// 查找包含特定文本的单元格
QList<QTableWidgetItem*> foundItems = tableWidget->findItems("张三", Qt::MatchExactly);
foreach (QTableWidgetItem *item, foundItems) {
    tableWidget->setCurrentItem(item); // 定位到找到的项
    tableWidget->scrollToItem(item);   // 滚动到该项
}

// 使用正则表达式查找
QList<QTableWidgetItem*> regexItems = tableWidget->findItems("^张.*", Qt::MatchRegExp);

✨ 3.4 信号和槽机制

cpp 复制代码
// 连接单元格内容变化信号
connect(tableWidget, &QTableWidget::cellChanged, [=](int row, int column){
    QTableWidgetItem *item = tableWidget->item(row, column);
    qDebug() << QString("第%1行第%2列内容改变为:%3")
                .arg(row + 1).arg(column + 1).arg(item->text());
});

// 连接单元格点击信号
connect(tableWidget, &QTableWidget::cellClicked, [=](int row, int column){
    qDebug() << QString("点击了第%1行第%2列").arg(row + 1).arg(column + 1);
});

// 连接单元格双击信号
connect(tableWidget, &QTableWidget::cellDoubleClicked, [=](int row, int column){
    QTableWidgetItem *item = tableWidget->item(row, column);
    if (item) {
        qDebug() << "双击:" << item->text();
    }
});

// 连接选择变化信号
connect(tableWidget, &QTableWidget::itemSelectionChanged, [=](){
    qDebug() << "选中项发生变化,当前选中" << tableWidget->selectedItems().count() << "个单元格";
});

🎄四、完整例子代码:学生信息管理系统

这个小节提供一个完整例子代码,使用Qt5.12.12已运行通过的。

✨ 4.1 项目结构

复制代码
QTableWidgetTest/
├── QTableWidgetTest.pro    # 项目文件
├── main.cpp                # 程序入口
├── mainwindow.h            # 主窗口头文件
└── mainwindow.cpp          # 主窗口实现文件

✨ 4.2 项目代码

QTableWidgetTest.pro

复制代码
QT       += core gui widgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11 utf8_source

# 确保使用UTF-8编码
CODECFORSRC = UTF-8
CODECFORTR = UTF-8

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

main.cpp

cpp 复制代码
#include "mainwindow.h"
#include <QApplication>
#include <QTextCodec>
#include <QFont>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 设置应用程序编码为UTF-8
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
#else
    // Qt5 默认使用UTF-8,但可以显式设置
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
#endif

    // 设置应用程序样式
    a.setStyle("Fusion");

    QFont font;

    // Windows系统
#ifdef Q_OS_WIN
    font.setFamily("Microsoft YaHei");
    qDebug() << "Windows系统,使用 Microsoft YaHei 字体";

    // Linux系统
#elif defined(Q_OS_LINUX)
    font.setFamily("WenQuanYi Micro Hei");
    qDebug() << "Linux系统,使用 WenQuanYi Micro Hei 字体";

    // macOS系统
#elif defined(Q_OS_MAC)
    font.setFamily("PingFang SC");
    qDebug() << "macOS系统,使用 PingFang SC 字体";

    // 其他系统
#else
    font.setFamily("Arial");
    qDebug() << "其他系统,使用 Arial 字体";
#endif
    font.setPointSize(9);
    a.setFont(font);

    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTableWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
#include <QHeaderView>
#include <QComboBox>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void initTable();           // 初始化表格
    void addStudent();          // 添加学生
    void deleteStudent();       // 删除选中学生
    void calculateTotal();      // 计算总分
    void sortByScore();         // 按成绩排序
    void searchStudent();       // 查找学生
    void onCellChanged(int row, int column); // 单元格内容变化
    void setScoreColor(QTableWidgetItem *item, int score);

private:
    void setupUI();             // 设置界面
    void setupConnections();    // 连接信号槽

    QTableWidget *tableWidget;  // 表格控件
    QPushButton *btnAdd;        // 添加按钮
    QPushButton *btnDelete;     // 删除按钮
    QPushButton *btnCalculate;  // 计算按钮
    QPushButton *btnSort;       // 排序按钮
    QPushButton *btnSearch;     // 搜索按钮
    QLineEdit *searchEdit;      // 搜索框
    QComboBox *searchColumn;    // 搜索列选择
};

#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include <QStatusBar>
#include <QMessageBox>
#include <QHeaderView>
#include <QRandomGenerator>
#include <QSet>
#include <QBrush>
#include <QFont>
#include <QDateTime>
#include <algorithm>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setupUI();
    setupConnections();
    initTable();
    setWindowTitle("学生信息管理系统 - Qt5.12.12");
    resize(1200, 700);
}

MainWindow::~MainWindow()
{
}

void MainWindow::setupUI()
{
    // 创建中央部件和布局
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);

    // 创建工具栏
    QHBoxLayout *toolLayout = new QHBoxLayout();

    btnAdd = new QPushButton("添加学生", this);
    btnDelete = new QPushButton("删除选中", this);
    btnCalculate = new QPushButton("计算总分", this);
    btnSort = new QPushButton("按总分排序", this);

    // 搜索区域
    QLabel *searchLabel = new QLabel("搜索:", this);
    searchEdit = new QLineEdit(this);
    searchEdit->setPlaceholderText("输入搜索内容...");
    searchEdit->setMaximumWidth(200);

    searchColumn = new QComboBox(this);
    searchColumn->addItem("所有列");
    searchColumn->addItem("学号");
    searchColumn->addItem("姓名");
    searchColumn->addItem("专业");
    searchColumn->setMaximumWidth(100);

    btnSearch = new QPushButton("搜索", this);

    // 添加到工具栏
    toolLayout->addWidget(btnAdd);
    toolLayout->addWidget(btnDelete);
    toolLayout->addWidget(btnCalculate);
    toolLayout->addWidget(btnSort);
    toolLayout->addStretch();
    toolLayout->addWidget(searchLabel);
    toolLayout->addWidget(searchEdit);
    toolLayout->addWidget(searchColumn);
    toolLayout->addWidget(btnSearch);

    // 创建表格
    tableWidget = new QTableWidget(this);
    tableWidget->setRowCount(20);
    tableWidget->setColumnCount(10);

    // 设置表头
    QStringList headers;
    headers << "学号" << "姓名" << "性别" << "年龄"
            << "专业" << "班级" << "语文" << "数学"
            << "英语" << "总分";
    tableWidget->setHorizontalHeaderLabels(headers);

    // 设置表格属性
    tableWidget->setEditTriggers(QAbstractItemView::DoubleClicked);
    tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    tableWidget->setAlternatingRowColors(true);

    // 设置列宽
    tableWidget->setColumnWidth(0, 100);  // 学号
    tableWidget->setColumnWidth(1, 80);   // 姓名
    tableWidget->setColumnWidth(2, 60);   // 性别
    tableWidget->setColumnWidth(3, 60);   // 年龄
    tableWidget->setColumnWidth(4, 120);  // 专业
    tableWidget->setColumnWidth(5, 80);   // 班级
    for (int i = 6; i <= 9; ++i) {
        tableWidget->setColumnWidth(i, 80); // 成绩列
    }

    // 设置行高
    for (int i = 0; i < 20; ++i) {
        tableWidget->setRowHeight(i, 30);
    }

    // 添加到主布局
    mainLayout->addLayout(toolLayout);
    mainLayout->addWidget(tableWidget);

    // 设置状态栏
    statusBar()->showMessage("就绪 - 共20名学生信息");

    setCentralWidget(centralWidget);
}

void MainWindow::setupConnections()
{
    connect(btnAdd, &QPushButton::clicked, this, &MainWindow::addStudent);
    connect(btnDelete, &QPushButton::clicked, this, &MainWindow::deleteStudent);
    connect(btnCalculate, &QPushButton::clicked, this, &MainWindow::calculateTotal);
    connect(btnSort, &QPushButton::clicked, this, &MainWindow::sortByScore);
    connect(btnSearch, &QPushButton::clicked, this, &MainWindow::searchStudent);
    connect(tableWidget, &QTableWidget::cellChanged, this, &MainWindow::onCellChanged);
}

void MainWindow::initTable()
{
    // 禁用排序,避免初始化时触发排序
    tableWidget->setSortingEnabled(false);

    // 预定义数据
    QStringList names = {"张三", "李四", "王五", "赵六", "钱七",
                        "孙八", "周九", "吴十", "郑十一", "王十二",
                        "刘十三", "陈十四", "杨十五", "黄十六", "赵十七",
                        "周十八", "吴十九", "郑二十", "孙二十一", "李二十二"};

    QStringList genders = {"男", "女"};
    QStringList majors = {"计算机科学", "软件工程", "信息安全",
                         "人工智能", "数据科学", "网络工程"};

    // 填充表格数据
    for (int row = 0; row < 20; ++row) {
        // 学号
        QTableWidgetItem *idItem = new QTableWidgetItem(QString("202300%1").arg(row + 1, 3, 10, QChar('0')));
        idItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(row, 0, idItem);

        // 姓名
        QTableWidgetItem *nameItem = new QTableWidgetItem(names[row % names.size()]);
        nameItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(row, 1, nameItem);

        // 性别
        QTableWidgetItem *genderItem = new QTableWidgetItem(genders[row % 2]);
        genderItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(row, 2, genderItem);

        // 年龄
        int age = 18 + row % 5;
        QTableWidgetItem *ageItem = new QTableWidgetItem(QString::number(age));
        ageItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(row, 3, ageItem);

        // 专业
        QTableWidgetItem *majorItem = new QTableWidgetItem(majors[row % majors.size()]);
        majorItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(row, 4, majorItem);

        // 班级
        QTableWidgetItem *classItem = new QTableWidgetItem(QString("Class %1").arg((row % 3) + 1));
        classItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(row, 5, classItem);

        // 生成随机成绩 (60-100)
        int chinese = 60 + QRandomGenerator::global()->bounded(40);
        int math = 60 + QRandomGenerator::global()->bounded(40);
        int english = 60 + QRandomGenerator::global()->bounded(40);

        // 语文成绩
        QTableWidgetItem *chineseItem = new QTableWidgetItem(QString::number(chinese));
        chineseItem->setTextAlignment(Qt::AlignCenter);
        setScoreColor(chineseItem, chinese);
        tableWidget->setItem(row, 6, chineseItem);

        // 数学成绩
        QTableWidgetItem *mathItem = new QTableWidgetItem(QString::number(math));
        mathItem->setTextAlignment(Qt::AlignCenter);
        setScoreColor(mathItem, math);
        tableWidget->setItem(row, 7, mathItem);

        // 英语成绩
        QTableWidgetItem *englishItem = new QTableWidgetItem(QString::number(english));
        englishItem->setTextAlignment(Qt::AlignCenter);
        setScoreColor(englishItem, english);
        tableWidget->setItem(row, 8, englishItem);

        // 总分(初始为0,需要计算)
        QTableWidgetItem *totalItem = new QTableWidgetItem("0");
        totalItem->setTextAlignment(Qt::AlignCenter);
        totalItem->setBackground(QBrush(QColor("#E3F2FD")));
        totalItem->setFont(QFont("Arial", 10, QFont::Bold));
        tableWidget->setItem(row, 9, totalItem);
    }

    // 计算初始总分
    calculateTotal();

    // 启用排序
    tableWidget->setSortingEnabled(true);
}

void MainWindow::setScoreColor(QTableWidgetItem *item, int score)
{
    if (score >= 90) {
        item->setBackground(QBrush(QColor("#C8E6C9"))); // 优秀:浅绿色
        item->setForeground(QBrush(QColor("#1B5E20")));
    } else if (score >= 80) {
        item->setBackground(QBrush(QColor("#E8F5E9"))); // 良好:更浅绿色
        item->setForeground(QBrush(QColor("#33691E")));
    } else if (score >= 70) {
        item->setBackground(QBrush(QColor("#FFF9C4"))); // 中等:浅黄色
        item->setForeground(QBrush(QColor("#F57F17")));
    } else if (score >= 60) {
        item->setBackground(QBrush(QColor("#FFECB3"))); // 及格:橙色
        item->setForeground(QBrush(QColor("#EF6C00")));
    } else {
        item->setBackground(QBrush(QColor("#FFCDD2"))); // 不及格:浅红色
        item->setForeground(QBrush(QColor("#C62828")));
    }
}

void MainWindow::addStudent()
{
    int row = tableWidget->rowCount();
    tableWidget->insertRow(row);

    // 设置新行的默认值
    tableWidget->setItem(row, 0, new QTableWidgetItem(QString("202400%1").arg(row + 1, 3, 10, QChar('0'))));
    tableWidget->setItem(row, 1, new QTableWidgetItem("新学生"));
    tableWidget->setItem(row, 2, new QTableWidgetItem("男"));
    tableWidget->setItem(row, 3, new QTableWidgetItem("18"));
    tableWidget->setItem(row, 4, new QTableWidgetItem("计算机科学"));
    tableWidget->setItem(row, 5, new QTableWidgetItem("Class 1"));
    tableWidget->setItem(row, 6, new QTableWidgetItem("0"));
    tableWidget->setItem(row, 7, new QTableWidgetItem("0"));
    tableWidget->setItem(row, 8, new QTableWidgetItem("0"));
    tableWidget->setItem(row, 9, new QTableWidgetItem("0"));

    // 设置对齐方式
    for (int col = 0; col < 10; ++col) {
        QTableWidgetItem *item = tableWidget->item(row, col);
        if (item) {
            item->setTextAlignment(Qt::AlignCenter);
        }
    }

    statusBar()->showMessage(QString("已添加新学生,当前共%1名学生").arg(tableWidget->rowCount()));
}

void MainWindow::deleteStudent()
{
    QList<QTableWidgetItem*> selected = tableWidget->selectedItems();
    if (selected.isEmpty()) {
        QMessageBox::warning(this, "警告", "请先选择要删除的学生!");
        return;
    }

    // 获取选中的行(去重)
    QSet<int> rows;
    foreach (QTableWidgetItem *item, selected) {
        rows.insert(item->row());
    }

    // 从后往前删除,避免索引变化
    QList<int> rowList = rows.values();
    std::sort(rowList.begin(), rowList.end(), std::greater<int>());

    int count = 0;
    foreach (int row, rowList) {
        tableWidget->removeRow(row);
        count++;
    }

    statusBar()->showMessage(QString("已删除%1名学生,剩余%2名").arg(count).arg(tableWidget->rowCount()));
}

void MainWindow::calculateTotal()
{
    tableWidget->setSortingEnabled(false);

    for (int row = 0; row < tableWidget->rowCount(); ++row) {
        int total = 0;

        // 计算三科成绩之和
        for (int col = 6; col <= 8; ++col) {
            QTableWidgetItem *item = tableWidget->item(row, col);
            if (item && !item->text().isEmpty()) {
                bool ok;
                int score = item->text().toInt(&ok);
                if (ok) total += score;
            }
        }

        // 更新总分单元格
        QTableWidgetItem *totalItem = tableWidget->item(row, 9);
        if (!totalItem) {
            totalItem = new QTableWidgetItem();
            tableWidget->setItem(row, 9, totalItem);
        }
        totalItem->setText(QString::number(total));
        totalItem->setTextAlignment(Qt::AlignCenter);

        // 设置总分颜色
        if (total >= 270) {
            totalItem->setBackground(QBrush(QColor("#C8E6C9")));
        } else if (total >= 240) {
            totalItem->setBackground(QBrush(QColor("#E8F5E9")));
        } else if (total >= 210) {
            totalItem->setBackground(QBrush(QColor("#FFF9C4")));
        } else if (total >= 180) {
            totalItem->setBackground(QBrush(QColor("#FFECB3")));
        } else {
            totalItem->setBackground(QBrush(QColor("#FFCDD2")));
        }
    }

    tableWidget->setSortingEnabled(true);
    statusBar()->showMessage("总分计算完成");
}

void MainWindow::sortByScore()
{
    tableWidget->sortByColumn(9, Qt::DescendingOrder);
    statusBar()->showMessage("已按总分降序排序");
}

void MainWindow::searchStudent()
{
    QString keyword = searchEdit->text().trimmed();
    if (keyword.isEmpty()) {
        QMessageBox::information(this, "提示", "请输入搜索关键词");
        return;
    }

    // 清除之前的高亮
    for (int row = 0; row < tableWidget->rowCount(); ++row) {
        for (int col = 0; col < tableWidget->columnCount(); ++col) {
            QTableWidgetItem *item = tableWidget->item(row, col);
            if (item) {
                item->setBackground(QBrush());
            }
        }
    }

    int foundCount = 0;
    int searchCol = searchColumn->currentIndex() - 1; // -1表示搜索所有列

    for (int row = 0; row < tableWidget->rowCount(); ++row) {
        bool rowMatched = false;

        if (searchCol == -1) { // 搜索所有列
            for (int col = 0; col < tableWidget->columnCount(); ++col) {
                QTableWidgetItem *item = tableWidget->item(row, col);
                if (item && item->text().contains(keyword, Qt::CaseInsensitive)) {
                    item->setBackground(QBrush(QColor("#FFF176"))); // 高亮显示
                    rowMatched = true;
                }
            }
        } else { // 搜索指定列
            QTableWidgetItem *item = tableWidget->item(row, searchCol);
            if (item && item->text().contains(keyword, Qt::CaseInsensitive)) {
                item->setBackground(QBrush(QColor("#FFF176")));
                rowMatched = true;
            }
        }

        if (rowMatched) {
            foundCount++;
            tableWidget->setRowHidden(row, false);
        } else {
            tableWidget->setRowHidden(row, true);
        }
    }

    if (foundCount > 0) {
        statusBar()->showMessage(QString("找到%1条匹配记录").arg(foundCount));
    } else {
        statusBar()->showMessage("未找到匹配记录");
        // 显示所有行
        for (int row = 0; row < tableWidget->rowCount(); ++row) {
            tableWidget->setRowHidden(row, false);
        }
    }
}

void MainWindow::onCellChanged(int row, int column)
{
    // 如果修改的是成绩列,重新计算总分
    if (column >= 6 && column <= 8) {
        calculateTotal();
    }

    statusBar()->showMessage(QString("已更新第%1行第%2列数据").arg(row + 1).arg(column + 1));
}

✨ 4.3 运行效果与功能说明

主要功能

数据显示:展示20行×10列的学生信息

数据编辑:支持双击单元格编辑内容

学生管理:添加新学生、删除选中学生

成绩计算:自动计算三科总分并更新

数据排序:按总分降序排序

搜索功能:支持按关键词搜索学生

视觉反馈:根据成绩自动着色
界面特点

交替行颜色提高可读性

表头美化,使用绿色背景

成绩单元格根据分数范围自动着色

响应式布局,支持窗口调整大小

状态栏实时显示操作反馈
扩展建议

在实际应用中,还可以进一步扩展以下功能:

数据持久化:添加文件保存/加载功能

数据验证:添加输入验证(如成绩范围0-100)

导入导出:支持Excel/CSV格式导入导出

统计分析:添加平均分、最高分等统计功能

打印功能:支持表格打印

图表展示:使用Qt Charts展示成绩分布


🎄五、总结

QTableWidget 是 Qt 中功能强大且易于使用的表格控件,通过本文的详细介绍和完整示例,我们可以看到:

  • 基本使用简单:通过简单的行列设置即可创建表格

  • 功能丰富全面:支持数据操作、样式设置、排序查找等多种功能

  • 定制能力强:几乎可以定制表格的每一个视觉细节

  • 信号机制完善:提供了丰富的信号用于响应用户交互

对于学生信息管理、数据报表展示、配置参数编辑等场景,QTableWidget 都是一个优秀的选择。通过合理的封装和扩展,可以构建出功能完整、用户体验良好的表格应用程序。

最佳实践提示:

  • 对于大数据量(超过1000行),考虑使用 QTableView + 自定义模型

  • 在编辑数据前进行验证,确保数据有效性

  • 合理使用样式表,提升用户体验

  • 添加数据持久化功能,避免数据丢失

如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

相关推荐
用户8055336980320 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner20 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00613 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术13 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript