主页 > 开源代码  > 

QT基础十、表格组件:QTableWidget

QT基础十、表格组件:QTableWidget

目录

一、简介

二、主要特性

三、项目演练

1、新建一个项目,导入自己喜欢的图片

2、添加工具栏与action

 3、初始化数据

函数 initTableData

函数 createRowData

4、生成action与tabelWidget槽函数

函数 on_actionInsert_triggered()

函数 on_actionDel_triggered()

函数 on_actionEdit_triggered(bool checked)

函数 on_tableWidget_itemSelectionChanged()

5、增加搜索功能

在头文件mainwindow.h添加

函数 initLineEditSearch()

函数 on_searchBtn_clicked()

在tableWidget生成一个 on_tableWidget_cellClicked(int, int)

 6、运行结果

 四、项目代码

1、mainwindow.h

2、mainwindow.cpp


一、简介

QTableWidget 是 Qt 框架中的一个控件,用于显示和编辑表格数据。它是基于 QTableView 的高级实现,提供了一个更简单、更直接的方式来操作表格数据,而无需深入理解底层的模型-视图架构(Model-View Architecture)。QTableWidget 内部使用了默认的 QTableWidgetItem 来存储和管理表格中的单元格数据。


二、主要特性

表格结构 :

表格由行和列组成,每个单元格可以包含文本、图标或其他内容。支持动态调整行数和列数。

单元格操作 :

每个单元格的内容可以通过 QTableWidgetItem 进行设置和读取。支持单元格的编辑、选择、排序等操作。

交互功能 :

用户可以直接在单元格中输入或修改数据。支持多选模式(如单选、多选、扩展选择等)。

自定义外观 :

可以通过样式表(QSS)或自定义委托(Delegate)来改变表格的外观。支持设置表头(水平表头和垂直表头)的文本、图标等。

信号与槽 :

提供丰富的信号(如单元格点击、双击、选择变化等),方便开发者响应用户操作。
三、项目演练 1、新建一个项目,导入自己喜欢的图片

导入图片的步骤,我上一期已经演示过,这一期就不演示了,图片需要能代表头像、插入、编辑、删除。

2、添加工具栏与action

具体步骤我在上一期也演示了,文档实在是不好演示,若看上一期看不懂,建议看视频

 

 插入与输出不用勾选Checkable,编辑因为有编辑模式和非编辑模式,所以需要勾选Checkable

 ​​​​​​

 最终界面样式

 3、初始化数据

可以用数据库,不过我这一期不演示,以后会专门出一期数据库相关的知识

这里我们需要用到两个函数,initTableData() 是初始化整个表格数据,再将初始化一整行数据的功能封装成一个函数,可以减少代码的冗余度,因为你插入数据时也需要初始化一整行数据,到时候直接调用 createRowData() 函数就行。

函数 initTableData void MainWindow::initTableData() { // 定义表头内容:包括姓名、性别、出生日期、专业、是否毕业 QStringList headList = {"姓名", "性别", "出生日期", "专业", "是否毕业"}; // 设置表格的列数为表头的数量 ui->tableWidget->setColumnCount(headList.count()); // 遍历表头列表,设置每一列的表头项 for (int i = 0; i < headList.size(); i++) { // 创建一个新的 QTableWidgetItem 对象,用于存储表头文本 auto* item = new QTableWidgetItem(headList[i]); // 设置表头字体样式 QFont font = item->font(); font.setBold(true); // 字体加粗 font.setFamily("微软雅黑"); // 设置字体为微软雅黑 font.setPointSize(14); // 设置字体大小为 14 item->setFont(font); // 设置表头文字颜色为红色 item->setForeground(Qt::red); // 将表头项设置到表格的水平表头中 ui->tableWidget->setHorizontalHeaderItem(i, item); } // 获取表格的水平表头对象,并设置列宽自动伸展模式 auto* headerView = ui->tableWidget->horizontalHeader(); headerView->setSectionResizeMode(QHeaderView::Stretch); // 设置第二列(性别列)为固定宽度,不随窗口调整而变化 headerView->setSectionResizeMode(1, QHeaderView::Fixed); // 设置表格的行数为 100 行 int row = 100; ui->tableWidget->setRowCount(row); // 循环生成 100 行数据 for (int i = 0; i < row; i++) { maxNum++; // 员工编号递增 // 随机生成员工信息 QString name = QString::asprintf("员工%d", i + 1); // 姓名 QString sex = (rand() % 2) ? "男" : "女"; // 性别 QDate date(rand() % 10 + 2000, rand() % 12 + 1, rand() % 28 + 1); // 出生日期 QStringList subjects = {"软件工程", "计算机科学与技术", "通信工程", "网络工程"}; // 专业列表 bool graduate = (rand() % 2) ? true : false; // 是否毕业 // 调用 createRowData 函数,将生成的数据填充到表格中 createRowData(i, name, maxNum, sex, date, subjects[rand() % subjects.size()], graduate); } } 函数 createRowData void MainWindow::createRowData(int index, QString name, int number, QString sex, QDate birthday, QString subject, bool graduate) { // 创建一个 QList,用于存储每一行的 QTableWidgetItem 对象 QList<QTableWidgetItem*> items; // 姓名列 items.append(new QTableWidgetItem(name)); items[0]->setData(Qt::UserRole, QVariant(number)); // 使用 UserRole 存储员工编号 // 性别列 items.append(new QTableWidgetItem(sex)); QIcon icon((sex == "男") ? ":/image/boy.png" : ":/image/girl.png"); // 根据性别设置图标 items[1]->setIcon(icon); // 出生日期列 items.append(new QTableWidgetItem(birthday.toString("yyyy-MM-dd"))); // 格式化日期为字符串 // 专业列 items.append(new QTableWidgetItem(subject)); // 是否毕业列 items.append(new QTableWidgetItem(graduate ? "已毕业" : "未毕业")); // 循环遍历所有列,设置单元格内容居中对齐,并将其添加到表格中 for (int i = 0; i < items.size(); i++) { items[i]->setTextAlignment(Qt::AlignCenter); // 设置单元格内容居中对齐 ui->tableWidget->setItem(index, i, items[i]); // 将单元格内容设置到表格中 } } 4、生成action与tabelWidget槽函数

注:插入与删除,选择 triggered();编辑,选择triggered(bool)

函数 on_actionInsert_triggered() void MainWindow::on_actionInsert_triggered() { //取出当前选中的行号,并记录插入的行号 int row = insertRow = ui->tableWidget->currentRow(); ui->tableWidget->insertRow(row); maxNum++; // 员工编号递增 // 随机生成员工信息 QString name = "未知"; QString sex = "男"; QDate date(2000, 1, 1); QString subject = "未知"; bool graduate = false; // 调用 createRowData 函数,将生成的数据填充到表格中 createRowData(row, name, maxNum, sex, date, subject, graduate); //插入后,自动选择新行 ui->tableWidget->selectRow(row); on_actionEdit_triggered(true); } 函数 on_actionDel_triggered() void MainWindow::on_actionDel_triggered() { // 获取当前选中的单元格项 auto* item = ui->tableWidget->currentItem(); // 检查该项是否被选中 if (item && item->isSelected()) { // 删除该项所在的整行 ui->tableWidget->removeRow(item->row()); } } 函数 on_actionEdit_triggered(bool checked) void MainWindow::on_actionEdit_triggered(bool checked) { if (checked) { // 如果编辑模式被启用,则设置编辑触发器为双击或单击选中项 ui->tableWidget->setEditTriggers( QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); } else { // 如果编辑模式被禁用,则禁止所有编辑触发器 ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); } } 函数 on_tableWidget_itemSelectionChanged() //当用户选择不同的行时,系统会自动检查是否需要禁用编辑模式。 //只有在特定行(如插入行)中才允许编辑,其他行不允许编辑。 void MainWindow::on_tableWidget_itemSelectionChanged() { // 如果编辑模式已启用,则直接返回,不做任何处理 if (ui->actionEdit->isChecked()) return; // 如果当前选中的行不是插入行(insertRow),则禁用编辑模式 if (ui->tableWidget->currentRow() != insertRow) { on_actionEdit_triggered(false); } } 5、增加搜索功能

注:状态栏不好进行图形化拖拽,所以这里用代码实现

在头文件mainwindow.h添加 //私有槽函数 private slots: void on_searchBtn_clicked(); //私有函数 private: void initLineEditSearch(); //私有变量 private: QLabel* label; //搜索 QLabel* info; //提示 QLineEdit* lineEditSearch; //搜索内容 QPushButton* searchBtn; //搜索按钮 函数 initLineEditSearch() void MainWindow::initLineEditSearch() { // 创建一个 QLabel 对象,并设置其文本为“搜索” label = new QLabel(this); label->setText("搜索"); // 设置标签的字体大小为 14 auto font = label->font(); font.setPointSize(14); label->setFont(font); // 将标签添加到状态栏中 ui->statusbar->addWidget(label); // 创建一个 QLineEdit 对象,用于输入搜索内容 lineEditSearch = new QLineEdit(this); // 设置 QLineEdit 的最大宽度为 400 像素,避免占用过多空间 lineEditSearch->setMaximumWidth(400); // 将 QLineEdit 添加到状态栏中 ui->statusbar->addWidget(lineEditSearch); // 创建一个 QPushButton 对象,并设置其文本为“查找” searchBtn = new QPushButton(this); searchBtn->setText("查找"); // 设置按钮的字体大小为 14 font = searchBtn->font(); font.setPointSize(14); searchBtn->setFont(font); // 将按钮添加到状态栏中 ui->statusbar->addWidget(searchBtn); // 连接按钮的 clicked() 信号到槽函数 on_searchBtn_clicked() connect(searchBtn, SIGNAL(clicked()), this, SLOT(on_searchBtn_clicked())); // 创建一个 QLabel 对象,用于显示搜索结果或提示信息 info = new QLabel(this); // 将信息标签添加到状态栏中 ui->statusbar->addWidget(info); } 函数 on_searchBtn_clicked() void MainWindow::on_searchBtn_clicked() { // 清除表格中之前的所有高亮选择 ui->tableWidget->clearSelection(); // 获取用户在搜索框中输入的关键字,并去除首尾空格 QString key = lineEditSearch->text().trimmed(); // 检查关键字是否非空 if (key.length() > 0) { // 使用 findItems 方法查找包含关键字的所有项 auto items = ui->tableWidget->findItems(key, Qt::MatchContains); // 遍历查找到的所有项,并将其设置为选中状态(高亮显示) for (auto it = items.constBegin(); it != items.constEnd(); it++) { (*it)->setSelected(true); } } } 在tableWidget生成一个 on_tableWidget_cellClicked(int, int)

void MainWindow::on_tableWidget_cellClicked(int row, int column) { // 定义一个字符串变量,用于存储当前行的所有单元格内容 QString infoStr; // 遍历表格的每一列,获取当前行的所有单元格内容 for (int i = 0; i < ui->tableWidget->columnCount(); i++) { // 如果不是第一列,在内容前添加分隔符 "/" if (i) infoStr += "/"; // 获取当前行第 i 列的单元格内容,并追加到 infoStr 中 infoStr += ui->tableWidget->item(row, i)->text(); } // 将拼接好的字符串设置到信息标签中,显示在状态栏上 info->setText(infoStr); }  6、运行结果


 四、项目代码 1、mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QDate> #include <QLineEdit> #include <QLabel> #include <QPushButton> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_actionInsert_triggered(); void on_actionDel_triggered(); void on_actionEdit_triggered(bool checked); void on_tableWidget_itemSelectionChanged(); void on_searchBtn_clicked(); void on_tableWidget_cellClicked(int row, int column); private: void initTableData(); //姓名、性别、出生日期、专业、是否毕业 void createRowData(int index, QString name, int number, QString sex, QDate birthday, QString subject, bool graduate); void initLineEditSearch(); private: Ui::MainWindow *ui; QLabel* label; QLabel* info; QLineEdit* lineEditSearch; QPushButton* searchBtn; int maxNum; int insertRow; }; #endif // MAINWINDOW_H 2、mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) , maxNum(0) { ui->setupUi(this); initTableData(); //禁止编辑 ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); initLineEditSearch(); ui->tableWidget->setStyleSheet( "selection-background-color:rgb(255, 128, 0)"); } MainWindow::~MainWindow() { delete ui; } void MainWindow::initTableData() { // 定义表头内容:包括姓名、性别、出生日期、专业、是否毕业 QStringList headList = {"姓名", "性别", "出生日期", "专业", "是否毕业"}; // 设置表格的列数为表头的数量 ui->tableWidget->setColumnCount(headList.count()); // 遍历表头列表,设置每一列的表头项 for (int i = 0; i < headList.size(); i++) { // 创建一个新的 QTableWidgetItem 对象,用于存储表头文本 auto* item = new QTableWidgetItem(headList[i]); // 设置表头字体样式 QFont font = item->font(); font.setBold(true); // 字体加粗 font.setFamily("微软雅黑"); // 设置字体为微软雅黑 font.setPointSize(14); // 设置字体大小为 14 item->setFont(font); // 设置表头文字颜色为红色 item->setForeground(Qt::red); // 将表头项设置到表格的水平表头中 ui->tableWidget->setHorizontalHeaderItem(i, item); } // 获取表格的水平表头对象,并设置列宽自动伸展模式 auto* headerView = ui->tableWidget->horizontalHeader(); headerView->setSectionResizeMode(QHeaderView::Stretch); // 设置第二列(性别列)为固定宽度,不随窗口调整而变化 headerView->setSectionResizeMode(1, QHeaderView::Fixed); // 设置表格的行数为 100 行 int row = 100; ui->tableWidget->setRowCount(row); // 循环生成 100 行数据 for (int i = 0; i < row; i++) { maxNum++; // 员工编号递增 // 随机生成员工信息 QString name = QString::asprintf("员工%d", i + 1); // 姓名 QString sex = (rand() % 2) ? "男" : "女"; // 性别 QDate date(rand() % 10 + 2000, rand() % 12 + 1, rand() % 28 + 1); // 出生日期 QStringList subjects = {"软件工程", "计算机科学与技术", "通信工程", "网络工程"}; // 专业列表 bool graduate = (rand() % 2) ? true : false; // 是否毕业 // 调用 createRowData 函数,将生成的数据填充到表格中 createRowData(i, name, maxNum, sex, date, subjects[rand() % subjects.size()], graduate); } } void MainWindow::createRowData(int index, QString name, int number, QString sex, QDate birthday, QString subject, bool graduate) { // 创建一个 QList,用于存储每一行的 QTableWidgetItem 对象 QList<QTableWidgetItem*> items; // 姓名列 items.append(new QTableWidgetItem(name)); items[0]->setData(Qt::UserRole, QVariant(number)); // 使用 UserRole 存储员工编号 // 性别列 items.append(new QTableWidgetItem(sex)); QIcon icon((sex == "男") ? ":/image/boy.png" : ":/image/girl.png"); // 根据性别设置图标 items[1]->setIcon(icon); // 出生日期列 items.append(new QTableWidgetItem(birthday.toString("yyyy-MM-dd"))); // 格式化日期为字符串 // 专业列 items.append(new QTableWidgetItem(subject)); // 是否毕业列 items.append(new QTableWidgetItem(graduate ? "已毕业" : "未毕业")); // 循环遍历所有列,设置单元格内容居中对齐,并将其添加到表格中 for (int i = 0; i < items.size(); i++) { items[i]->setTextAlignment(Qt::AlignCenter); // 设置单元格内容居中对齐 ui->tableWidget->setItem(index, i, items[i]); // 将单元格内容设置到表格中 } } void MainWindow::initLineEditSearch() { // 创建一个 QLabel 对象,并设置其文本为“搜索” label = new QLabel(this); label->setText("搜索"); // 设置标签的字体大小为 14 auto font = label->font(); font.setPointSize(14); label->setFont(font); // 将标签添加到状态栏中 ui->statusbar->addWidget(label); // 创建一个 QLineEdit 对象,用于输入搜索内容 lineEditSearch = new QLineEdit(this); // 设置 QLineEdit 的最大宽度为 400 像素,避免占用过多空间 lineEditSearch->setMaximumWidth(400); // 将 QLineEdit 添加到状态栏中 ui->statusbar->addWidget(lineEditSearch); // 创建一个 QPushButton 对象,并设置其文本为“查找” searchBtn = new QPushButton(this); searchBtn->setText("查找"); // 设置按钮的字体大小为 14 font = searchBtn->font(); font.setPointSize(14); searchBtn->setFont(font); // 将按钮添加到状态栏中 ui->statusbar->addWidget(searchBtn); // 连接按钮的 clicked() 信号到槽函数 on_searchBtn_clicked() connect(searchBtn, SIGNAL(clicked()), this, SLOT(on_searchBtn_clicked())); // 创建一个 QLabel 对象,用于显示搜索结果或提示信息 info = new QLabel(this); // 将信息标签添加到状态栏中 ui->statusbar->addWidget(info); } void MainWindow::on_actionInsert_triggered() { //取出当前选中的行号,并记录插入的行号 int row = insertRow = ui->tableWidget->currentRow(); ui->tableWidget->insertRow(row); maxNum++; // 员工编号递增 // 随机生成员工信息 QString name = "未知"; QString sex = "男"; QDate date(2000, 1, 1); QString subject = "未知"; bool graduate = false; // 调用 createRowData 函数,将生成的数据填充到表格中 createRowData(row, name, maxNum, sex, date, subject, graduate); //插入后,自动选择新行 ui->tableWidget->selectRow(row); on_actionEdit_triggered(true); } void MainWindow::on_actionDel_triggered() { // 获取当前选中的单元格项 auto* item = ui->tableWidget->currentItem(); // 检查该项是否被选中 if (item && item->isSelected()) { // 删除该项所在的整行 ui->tableWidget->removeRow(item->row()); } } void MainWindow::on_actionEdit_triggered(bool checked) { if (checked) { // 如果编辑模式被启用,则设置编辑触发器为双击或单击选中项 ui->tableWidget->setEditTriggers( QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); } else { // 如果编辑模式被禁用,则禁止所有编辑触发器 ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); } } void MainWindow::on_tableWidget_itemSelectionChanged() { // 如果编辑模式已启用,则直接返回,不做任何处理 if (ui->actionEdit->isChecked()) return; // 如果当前选中的行不是插入行(insertRow),则禁用编辑模式 if (ui->tableWidget->currentRow() != insertRow) { on_actionEdit_triggered(false); } } void MainWindow::on_searchBtn_clicked() { // 清除表格中之前的所有高亮选择 ui->tableWidget->clearSelection(); // 获取用户在搜索框中输入的关键字,并去除首尾空格 QString key = lineEditSearch->text().trimmed(); // 检查关键字是否非空 if (key.length() > 0) { // 使用 findItems 方法查找包含关键字的所有项 auto items = ui->tableWidget->findItems(key, Qt::MatchContains); // 遍历查找到的所有项,并将其设置为选中状态(高亮显示) for (auto it = items.constBegin(); it != items.constEnd(); it++) { (*it)->setSelected(true); } } } void MainWindow::on_tableWidget_cellClicked(int row, int column) { // 定义一个字符串变量,用于存储当前行的所有单元格内容 QString infoStr; // 遍历表格的每一列,获取当前行的所有单元格内容 for (int i = 0; i < ui->tableWidget->columnCount(); i++) { // 如果不是第一列,在内容前添加分隔符 "/" if (i) infoStr += "/"; // 获取当前行第 i 列的单元格内容,并追加到 infoStr 中 infoStr += ui->tableWidget->item(row, i)->text(); } // 将拼接好的字符串设置到信息标签中,显示在状态栏上 info->setText(infoStr); }

标签:

QT基础十、表格组件:QTableWidget由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“QT基础十、表格组件:QTableWidget