1751 字
9 分钟
Qt学习笔记
QTabWidget相关笔记:
- 创建QTabWidget对象(这里只是创建了对象没有标签页,需要添加后才会有)
QTabWidget *tabWidget = new QTabWidget(this);- 设置初始显示项(可在构造函数中设置)
// 确保默认显示第一个标签页ui->tabWidget->setCurrentIndex(0);- 添加标签页
// 添加标签页ui->tabWidget->addTab(new QWidget(), "新标签页");- 切换标签页
// 切换到第二个标签页ui->tabWidget->setCurrentIndex(1);- 获取当前标签页索引
// 获取当前选中的标签页索引int currentIndex = ui->tabWidget->currentIndex();- 获取标签页数量
// 获取标签页数量int tabCount = ui->tabWidget->count();- 删除标签页
// 删除第二个标签页ui->tabWidget->removeTab(1);- 获取标签页标题
// 获取第二个标签页的标题QString tabText = ui->tabWidget->tabText(1);- 设置标签页标题
// 设置第二个标签页的标题ui->tabWidget->setTabText(1, "新标题");- 获取标签页图标
// 获取第二个标签页的图标QIcon tabIcon = ui->tabWidget->tabIcon(1);- 设置标签页图标
// 设置第二个标签页的图标ui->tabWidget->setTabIcon(1, QIcon(":/icon/2.png"));QTableWidget相关笔记:
- 设置行数
// 设置表格行数ui->tableWidget->setRowCount(3);- 设置列数
// 设置表格列数ui->tableWidget->setColumnCount(3);- 设置表头(水平方向)
// 设置表格表头ui->tableWidget->setHorizontalHeaderLabels({"姓名", "年龄", "性别"});表头的数量与列数相同,即3列就有3个表头。
- 设置表头(垂直方向)
// 设置表格表头ui->tableWidget->setVerticalHeaderLabels({"行1", "行2", "行3"});表头的数量与行数相同,即3行就有3个表头。
- 隐藏垂直表头(行号)
// 隐藏垂直表头(行号)ui->tableWidget->verticalHeader()->setVisible(false);- 隐藏水平表头(列号)
// 隐藏水平表头(列号)ui->tableWidget->horizontalHeader()->setVisible(false);- 设置表格的列宽
// 设置表格的列宽ui->tableWidget->setColumnWidth(0, 100); // 第一列宽度为100ui->tableWidget->setColumnWidth(1, 150); // 第二列宽度为150ui->tableWidget->setColumnWidth(2, 200); // 第三列宽度为200
//统一设置一样的列宽ui->tableWidget->horizontalHeader()->setDefaultSectionSize(tmpform->width());//这里的tmpform是一个QWidget对象
//设置弹性布局(自动调整大小)ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 根据内容调整ui->tableWidget->resizeColumnsToContents();注意:使用上面的设置表格所有行的默认高度为 tmpform 的宽度以及设置弹性布局(自动调整大小),需要添加头文件#include <QHeaderView>,否则会报错。
- 设置行高
// 设置表格的行高ui->tableWidget->setRowHeight(0, 50); // 第一行高度为50ui->tableWidget->setRowHeight(1, 70); // 第二行高度为70ui->tableWidget->setRowHeight(2, 90); // 第三行高度为90
//统一设置一样的列宽ui->tableWidget->horizontalHeader()->setDefaultSectionSize(tmpform->width());//这里的tmpform是一个QWidget对象
//设置弹性布局(自动调整大小)ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 根据内容调整ui->tableWidget->resizeRowsToContents();注意:使用上面的设置表格所有行的默认宽度为 tmpform 的宽度以及设置弹性布局(自动调整大小),需要添加头文件#include <QHeaderView>,否则会报错。
- 获取表格的行数和列数
// 获取表格的行数和列数int rowCount = ui->tableWidget->rowCount();int columnCount = ui->tableWidget->columnCount();QSqlTableModel相关笔记:
- 创建QSqlTableModel对象:
QSqlTableModel *model = new QSqlTableModel(this);- 设置数据表名:
model->setTable("table_name");- 设置编辑策略(重要!)
model->setEditStrategy(QSqlTableModel::OnManualSubmit);QSqlTableModel有三种编辑策略:
-
OnFieldChange:所有更改立即提交到数据库(性能较差) -
OnRowChange:当用户选择不同行时提交更改(默认策略) -
OnManualSubmit:所有更改缓存起来,直到调用submitAll()(推荐用于复杂操作)
- 设置表头标签(可选)
model->setHeaderData(0, Qt::Horizontal, "姓名");model->setHeaderData(1, Qt::Horizontal, "年龄");model->setHeaderData(2, Qt::Horizontal, "性别");- 提交数据:
model->submitAll();// 获取详细错误信息if (!model->submitAll()) { QSqlError error = model->lastError(); qDebug() << "错误类型:" << error.type(); qDebug() << "错误文本:" << error.text(); qDebug() << "数据库错误:" << error.databaseText(); qDebug() << "驱动错误:" << error.driverText(); qDebug() << "错误代码:" << error.nativeErrorCode();}- 设置查询条件(相当于SQL的WHERE子句):
model->setFilter("age > 20");- 设置排序条件:
model->setSort(0, Qt::AscendingOrder); // 按第一列升序排序model->setSort(2, Qt::DescendingOrder); // 按第二列降序排列- 刷新数据:
model->select();- 获取数据:
// 获取第一行第一列的数据QVariant data = model->data(model->index(0, 0));- 获取数据行数:
int rowCount = model->rowCount();- 获取数据列数:
int columnCount = model->columnCount();- 获取数据列名:
QString columnName = model->headerData(0, Qt::Horizontal).toString();- 获取数据行名:
QString rowName = model->headerData(0, Qt::Vertical).toString();- 获取数据类型:
QVariant::Type dataType = model->data(model->index(0, 0)).type();- 修改数据示例:
// 修改第一行第一列的数据为"新值"model->setData(model->index(0, 0), "新值");- 删除数据列:
// 删除第一列model->removeColumn(0);- 添加数据列:
// 添加一列,列名设为"新列"model->insertColumn(model->columnCount());model->setHeaderData(model->columnCount() - 1, Qt::Horizontal, "新列");- 删除数据行:
// 删除第一行model->removeRow(0);
19. 直接数据访问方法:```c++// 方法1:使用record()访问数据[citation:1]for (int i = 0; i < model->rowCount(); ++i) { QSqlRecord record = model->record(i); QString name = record.value("name").toString(); int salary = record.value("salary").toInt(); qDebug() << name << salary;}
// 方法2:使用data()访问数据[citation:1]for (int row = 0; row < model->rowCount(); ++row) { QString name = model->data(model->index(row, 1)).toString(); int salary = model->data(model->index(row, 2)).toInt(); qDebug() << name << salary;}
// 更新数据示例[citation:1]for (int i = 0; i < model->rowCount(); ++i) { QSqlRecord record = model->record(i); double salary = record.value("salary").toDouble(); salary *= 1.1; // 涨薪10% record.setValue("salary", salary); model->setRecord(i, record);}model->submitAll();- 事务处理(重要!):
// 开始事务QSqlDatabase::database().transaction();
// 执行多个操作...model->setData(model->index(0, 0), "新值1");model->setData(model->index(1, 0), "新值2");bool success = model->submitAll();
// 根据结果提交或回滚if (success) { QSqlDatabase::database().commit();} else { QSqlDatabase::database().rollback(); model->revertAll(); // 撤销所有更改}- 性能优化技巧:
// 批量操作前关闭自动排序model->setSort(-1, Qt::AscendingOrder); // -1 表示不排序
// 批量操作完成后再设置排序model->setSort(column, Qt::AscendingOrder);model->select();
// 限制查询结果数量(大数据表)model->setFilter("1=1 LIMIT 1000"); // 只获取前1000条记录-
对于大量数据操作,使用OnManualSubmit策略
-
批量操作完成后一次性调用submitAll()
-
使用setFilter()和setSort()减少数据传输量
- 常用信号和槽:
// 数据更改前的信号connect(model, &QSqlTableModel::beforeUpdate, [](int row, QSqlRecord &record) { qDebug() << "准备更新行:" << row;});
// 数据插入前的信号connect(model, &QSqlTableModel::beforeInsert, [](QSqlRecord &record) { qDebug() << "准备插入新记录";});
// 数据删除前的信号connect(model, &QSqlTableModel::beforeDelete, [](int row) { qDebug() << "准备删除行:" << row;});
// primeInsert 信号(用于设置默认值)connect(model, &QSqlTableModel::primeInsert, [](int row, QSqlRecord &record) { record.setValue("create_time", QDateTime::currentDateTime()); record.setValue("status", "active");});- 与QTableView配合使用:
// 设置模型到视图QTableView *view = new QTableView;view->setModel(model);
// 设置选择行为view->setSelectionBehavior(QAbstractItemView::SelectRows); // 选择整行view->setSelectionMode(QAbstractItemView::SingleSelection); // 单选
// 隐藏不需要的列view->hideColumn(0); // 通常隐藏ID列
// 设置列宽自适应view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);- 数据验证:
// 重写setData方法进行数据验证class MySqlTableModel : public QSqlTableModel {protected: bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override { if (index.column() == 1) { // 假设第二列是年龄 int age = value.toInt(); if (age < 0 || age > 150) { return false; // 拒绝无效数据 } } return QSqlTableModel::setData(index, value, role); }};// 获取指定行列的数据QVariant value = model->data(model->index(row, column));
// 获取指定行列的数据(带角色参数)QVariant displayData = model->data(model->index(row, column), Qt::DisplayRole);
// 设置指定行列的数据model->setData(model->index(row, column), value);
// 设置指定行列的数据(带角色参数)model->setData(model->index(row, column), value, Qt::EditRole);
// 获取记录对象(包含该行所有字段)QSqlRecord record = model->record(row);
// 获取字段值QVariant fieldValue = record.value("fieldName");
// 设置字段值record.setValue("fieldName", newValue);model->setRecord(row, record);推荐使用方式:
- 数据读取:使用
model->data(model->index(row, column))- 最常用且高效 - 数据修改:使用
model->setData(model->index(row, column), value)- 简单直观 - 整行操作:使用
record()和setRecord()- 适合批量修改同一行的多个字段
最后更新于 2025-11-18,距今已过 3 天
部分内容可能已过时