如何用QTableWidget实现查询功能?

摘要:Qt 是一个跨平台C++图形界面平台,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍`TableWidg
Qt 技巧笔记(十四):QTableWidget 表格组件 ​ Qt 是一个跨平台C++图形界面平台,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍TableWidget表格组件的常用方法及灵活运用。其核心特点: 内置数据存储模型(QTableWidgetItem) 支持单元格级别的编辑和选择 提供行列表头、单元格式的高度自定义能力 包含丰富的信号槽机制,便于交互响应 其QTableWidget类层次结构: QObject └── QWidget └── QFrame └── QAbstractScrollArea └── QAbstractItemView └── QTableView └── QTableWidget QTableWidget 继承自 QTableView 类,QTableView 类也可以用来显示表格控件。QTableWidget 可以看做是 QTableView 的“简易版”或者“升级版”,它们的区别在于: QTableWidget 使用起来更简单,而 QTableView 的用法相对比较复杂。 QTableView 可以存储大量的数据(例如几十万甚至几百万),用户浏览表格中的数据时不会出现卡顿等现象;尽管 QTableWidget 也能用来存储大量的数据,但用户使用时可能出现卡顿等现象,且显示的数据越多,类似的现象越明显。 总之,QTableWidget 只适合显示少量的数据(几百或几千个),如果想要显示更多的数据,应该用 QTableView。此外,QTableView 还有一些更高级的用法,我们会在讲解 QTableView 时做重点介绍。 1.1 QTableWidget 的基本API接口汇总 ​ QTableWidget是Qt中用于显示表格数据的部件。它是QTableView的子类,提供了一个简单的接口,适用于一些不需要使用自定义数据模型的简单表格场景。QTableWidget提供了一个方便的接口来创建和操作表格中的数据。QTableWidget该组件可以看作是TreeWidget树形组件的高级版本,表格组件相较于树形结构组件灵活性更高,不仅提供了输出展示二维表格功能,还可以直接对表格元素直接进行编辑和修改操作,表格结构分为表头、表中数据两部分,表格结构可看作一个二维数组,通过数组行列即确定特定元素。 以下是QTableWidget类的一些常用方法API的简要说明: 表 1 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 的基本操作和配置的途径。使用这些方法,你可以动态地调整表格的大小、内容,设置表头,进行排序,处理编辑触发事件等。在.pro项目文件中添加必要的模块: QT += core gui widgets 下表展示了QTableWidget类提供的一些信号函数以及它们各种的,其常用的信号总结如下: 表 2 QTableWidget信号函数汇总 信号 触发条件与功能 cellClicked(int row,int column) 当某个单元格被点击时,触发该信号,row 和 columu 就是被点击的单元格的位置。 cellDoubleClicked(int row,int column) 当某个单元格被双击时,触发该信号,row 和 columu 就是被点击的单元格的位置。 cellEntered(int row,int column) 当某个单元格被按下时,触发该信号,row 和 columu 就是被点击的单元格的位置。 cellChanged(int row, int column) 当某个单元格中的数据发生改变时,触发该信号,row 和 columu 就是被改变的单元格的位置。 itemClicked(QTableWidgetItem *item) 当某个单元格被点击时,触发该信号,item 就是被点击的单元格。 itemDoubleClicked(QTableWidgetItem *item) 当某个单元格被双击时,触发该信号,item 就是被双击的单元格。 itemEntered(QTableWidgetItem *item) 当某个单元格被按下时,触发该信号,item 就是被按下的单元格。 itemChanged(QTableWidgetItem *item) 当某个单元格中的数据发生改变时,触发该信号,item 就是被改变的单元格。 activated(QModelIndex) 当用户激活index指定的项目时,发出信号 cellActivated(int row,int column) 单元格被激活时,发出信号,并传递(行,列) QTableWidget 表格也可以接收信号并做出相应地响应,例如: 表 3 QTableWidget常用槽函数 槽函数 功 能 clear() 删除表格中所有单元格的内容,包括表头。 clearContents() 不删除表头,仅删除表格中数据区内所有单元格的内容。 insertColumn(int column) 在表格第 column 列的位置插入一个空列 insertRow(int row) 在表格第 row 行的位置插入一个空行。 removeColumn(int column) 删除表格中的第 column 列,该列的所有单元格也会一并删除。 removeRow(int row) 删除表格中的第 row 行,该行的所有单元格也会一并删除。 scrollToItem(const QTableWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible) 滑动到指定的单元格。 其信号的中信号槽连接使用 QObject::connect,通常采用函数指针语法(Qt5/6 推荐)或宏 SIGNAL/SLOT 信号 连接示例 cellClicked(int row, int column) connect(table, &QTableWidget::cellClicked, this, &MyClass::onCellClicked); cellDoubleClicked(int row, int column) connect(table, &QTableWidget::cellDoubleClicked, ...); cellChanged(int row, int column) connect(table, &QTableWidget::cellChanged, ...); currentCellChanged(int currentRow, int currentCol, int previousRow, int previousCol) connect(table, &QTableWidget::currentCellChanged, ...); itemClicked(QTableWidgetItem *item) connect(table, &QTableWidget::itemClicked, ...); itemChanged(QTableWidgetItem *item) connect(table, &QTableWidget::itemChanged, ...) 示例: // 头文件声明槽函数 private slots: void onCellClicked(int row, int column); // 连接 connect(ui->tableWidget, &QTableWidget::cellClicked, this, &MyWidget::onCellClicked); // 实现 void MyWidget::onCellClicked(int row, int column) { qDebug() << "Clicked cell" << row << column; } 1.2 创建QTableWidget的表格 创建表格涉及到的成员函数有: // 构造函数 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 的基本方式一般有两种: // 方式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); 1.3 QTableWidget常用设置表格属性 ​ 我们需要总结常用的设置表格属性的API,包括行列、表头、选择模式、编辑触发、尺寸调整、样式等。可以按功能分类,给出API名称和简要说明。最好也提及对应的枚举值。 1.3.1 表头设置 方法 说明 setHorizontalHeaderLabels(list) 设置水平表头文字 setVerticalHeaderLabels(list) 设置垂直表头文字 horizontalHeader().setVisible(bool) 显示/隐藏水平表头 verticalHeader().setVisible(bool) 显示/隐藏垂直表头 1.3.2 选择行为与模式 方法 / 枚举 说明 setSelectionBehavior(QTableWidget.SelectionBehavior) 选择行为: SelectItems(单元格,默认) SelectRows(整行) SelectColumns(整列) setSelectionMode(QTableWidget.SelectionMode) 选择模式: NoSelection(禁止选择) SingleSelection(单选) MultiSelection(多选) ExtendedSelection(扩展选择,支持 Ctrl/Shift) ContiguousSelection(连续多选) 1.3.3 行列尺寸调整 方法 说明 resizeColumnsToContents() 所有列宽适应内容 resizeRowsToContents() 所有行高适应内容 setColumnWidth(int col, int width) 设置指定列宽(像素) setRowHeight(int row, int height) 设置指定行高(像素) horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode) 设置列宽调整模式: Interactive(用户可调,默认) Fixed(固定) Stretch(拉伸填满剩余空间) ResizeToContents(根据内容自动调整) verticalHeader().setSectionResizeMode(QHeaderView.ResizeMode) 同上,用于行高调整 1.3.4 外观样式 方法 说明 void setAlternatingRowColors(bool enable) 是否交替行颜色 void setShowGrid(bool show) 是否显示网格线 void setGridStyle(Qt::PenStyle style) 网格线样式:Qt::SolidLine, Qt::DashLine, Qt::DotLine 等 void setCornerButtonEnabled(bool enable) 左上角全选按钮是否可见 1.3.5 其他常用设置 方法 说明 void setSortingEnabled(bool enable) 是否启用点击表头排序 void setWordWrap(bool on) 单元格文本是否自动换行 void setTextElideMode(Qt::TextElideMode mode) 文本过长省略模式:Qt::ElideLeft, ElideRight, ElideMiddle, ElideNone 1.4 QTableWidget 示 例 QTableWidget提供了cellDoubleClicked信号,当用户双击单元格时触发该信号。通过连接该信号到自定义槽函数,可以获取被双击单元格的行列索引和内容。 #include <QApplication> #include <QTableWidget> #include <QMessageBox> #include <QHeaderView> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建表格控件 QTableWidget tableWidget(5, 3); // 5行3列 tableWidget.setWindowTitle("QTableWidget双击示例"); // 设置表头 QStringList headers; headers << "姓名" << "年龄" << "职业"; tableWidget.setHorizontalHeaderLabels(headers); // 填充示例数据 QStringList names = {"张三", "李四", "王五", "赵六", "钱七"}; QStringList jobs = {"工程师", "医生", "教师", "律师", "设计师"}; for(int row = 0; row < 5; ++row) { tableWidget.setItem(row, 0, new QTableWidgetItem(names[row])); tableWidget.setItem(row, 1, new QTableWidgetItem(QString::number(20 + row))); tableWidget.setItem(row, 2, new QTableWidgetItem(jobs[row])); } // 连接双击信号 QObject::connect(&tableWidget, &QTableWidget::cellDoubleClicked, [&](int row, int column){ QTableWidgetItem *item = tableWidget.item(row, column); QString message = QString("行: %1\n列: %2\n内容: %3") .arg(row + 1) .arg(column + 1) .arg(item ? item->text() : "空"); QMessageBox::information(&tableWidget, "单元格内容", message); }); // 调整列宽 tableWidget.horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); tableWidget.show(); return app.exec(); } 关键技术点说明 信号连接:使用QObject::connect将cellDoubleClicked信号连接到lambda表达式 行列索引:信号参数直接提供被双击单元格的行列索引(从0开始) 内容获取:通过item(row, column)方法获取QTableWidgetItem对象 空值处理:检查item指针是否为nullptr,避免空指针异常 界面反馈:使用QMessageBox显示获取到的单元格信息