【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 + 自定义模型

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

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

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

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

相关推荐
lsx2024063 小时前
FastAPI 交互式 API 文档
开发语言
VCR__3 小时前
python第三次作业
开发语言·python
码农水水3 小时前
得物Java面试被问:消息队列的死信队列和重试机制
java·开发语言·jvm·数据结构·机器学习·面试·职场和发展
东东5163 小时前
高校智能排课系统 (ssm+vue)
java·开发语言
余瑜鱼鱼鱼3 小时前
HashTable, HashMap, ConcurrentHashMap 之间的区别
java·开发语言
m0_736919103 小时前
模板编译期图算法
开发语言·c++·算法
【心态好不摆烂】3 小时前
C++入门基础:从 “这是啥?” 到 “好像有点懂了”
开发语言·c++
dyyx1113 小时前
基于C++的操作系统开发
开发语言·c++·算法
AutumnorLiuu3 小时前
C++并发编程学习(一)——线程基础
开发语言·c++·学习