1751 字
9 分钟

Qt学习笔记

2025-11-18
浏览量 加载中...

QTabWidget相关笔记:#

  1. 创建QTabWidget对象(这里只是创建了对象没有标签页,需要添加后才会有)
QTabWidget *tabWidget = new QTabWidget(this);
  1. 设置初始显示项(可在构造函数中设置)
// 确保默认显示第一个标签页
ui->tabWidget->setCurrentIndex(0);
  1. 添加标签页
// 添加标签页
ui->tabWidget->addTab(new QWidget(), "新标签页");
  1. 切换标签页
// 切换到第二个标签页
ui->tabWidget->setCurrentIndex(1);
  1. 获取当前标签页索引
// 获取当前选中的标签页索引
int currentIndex = ui->tabWidget->currentIndex();
  1. 获取标签页数量
// 获取标签页数量
int tabCount = ui->tabWidget->count();
  1. 删除标签页
// 删除第二个标签页
ui->tabWidget->removeTab(1);
  1. 获取标签页标题
// 获取第二个标签页的标题
QString tabText = ui->tabWidget->tabText(1);
  1. 设置标签页标题
// 设置第二个标签页的标题
ui->tabWidget->setTabText(1, "新标题");
  1. 获取标签页图标
// 获取第二个标签页的图标
QIcon tabIcon = ui->tabWidget->tabIcon(1);
  1. 设置标签页图标
// 设置第二个标签页的图标
ui->tabWidget->setTabIcon(1, QIcon(":/icon/2.png"));

QTableWidget相关笔记:#

  1. 设置行数
// 设置表格行数
ui->tableWidget->setRowCount(3);
  1. 设置列数
// 设置表格列数
ui->tableWidget->setColumnCount(3);
  1. 设置表头(水平方向)
// 设置表格表头
ui->tableWidget->setHorizontalHeaderLabels({"姓名", "年龄", "性别"});

表头的数量与列数相同,即3列就有3个表头。

  1. 设置表头(垂直方向)
// 设置表格表头
ui->tableWidget->setVerticalHeaderLabels({"行1", "行2", "行3"});

表头的数量与行数相同,即3行就有3个表头。

  1. 隐藏垂直表头(行号)
// 隐藏垂直表头(行号)
ui->tableWidget->verticalHeader()->setVisible(false);
  1. 隐藏水平表头(列号)
// 隐藏水平表头(列号)
ui->tableWidget->horizontalHeader()->setVisible(false);
  1. 设置表格的列宽
// 设置表格的列宽
ui->tableWidget->setColumnWidth(0, 100); // 第一列宽度为100
ui->tableWidget->setColumnWidth(1, 150); // 第二列宽度为150
ui->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>,否则会报错。

  1. 设置行高
// 设置表格的行高
ui->tableWidget->setRowHeight(0, 50); // 第一行高度为50
ui->tableWidget->setRowHeight(1, 70); // 第二行高度为70
ui->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>,否则会报错。

  1. 获取表格的行数和列数
// 获取表格的行数和列数
int rowCount = ui->tableWidget->rowCount();
int columnCount = ui->tableWidget->columnCount();

QSqlTableModel相关笔记:#

  1. 创建QSqlTableModel对象:
QSqlTableModel *model = new QSqlTableModel(this);
  1. 设置数据表名:
model->setTable("table_name");
  1. 设置编辑策略(重要!)
model->setEditStrategy(QSqlTableModel::OnManualSubmit);

QSqlTableModel有三种编辑策略:

  • OnFieldChange:所有更改立即提交到数据库(性能较差)

  • OnRowChange:当用户选择不同行时提交更改(默认策略)

  • OnManualSubmit:所有更改缓存起来,直到调用submitAll()(推荐用于复杂操作)

  1. 设置表头标签(可选)
model->setHeaderData(0, Qt::Horizontal, "姓名");
model->setHeaderData(1, Qt::Horizontal, "年龄");
model->setHeaderData(2, Qt::Horizontal, "性别");
  1. 提交数据:
model->submitAll();
// 获取详细错误信息
if (!model->submitAll()) {
QSqlError error = model->lastError();
qDebug() << "错误类型:" << error.type();
qDebug() << "错误文本:" << error.text();
qDebug() << "数据库错误:" << error.databaseText();
qDebug() << "驱动错误:" << error.driverText();
qDebug() << "错误代码:" << error.nativeErrorCode();
}
  1. 设置查询条件(相当于SQL的WHERE子句):
model->setFilter("age > 20");
  1. 设置排序条件:
model->setSort(0, Qt::AscendingOrder); // 按第一列升序排序
model->setSort(2, Qt::DescendingOrder); // 按第二列降序排列
  1. 刷新数据:
model->select();
  1. 获取数据:
// 获取第一行第一列的数据
QVariant data = model->data(model->index(0, 0));
  1. 获取数据行数:
int rowCount = model->rowCount();
  1. 获取数据列数:
int columnCount = model->columnCount();
  1. 获取数据列名:
QString columnName = model->headerData(0, Qt::Horizontal).toString();
  1. 获取数据行名:
QString rowName = model->headerData(0, Qt::Vertical).toString();
  1. 获取数据类型:
QVariant::Type dataType = model->data(model->index(0, 0)).type();
  1. 修改数据示例:
// 修改第一行第一列的数据为"新值"
model->setData(model->index(0, 0), "新值");
  1. 删除数据列:
// 删除第一列
model->removeColumn(0);
  1. 添加数据列:
// 添加一列,列名设为"新列"
model->insertColumn(model->columnCount());
model->setHeaderData(model->columnCount() - 1, Qt::Horizontal, "新列");
  1. 删除数据行:
// 删除第一行
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();
  1. 事务处理(重要!):
// 开始事务
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(); // 撤销所有更改
}
  1. 性能优化技巧:
// 批量操作前关闭自动排序
model->setSort(-1, Qt::AscendingOrder); // -1 表示不排序
// 批量操作完成后再设置排序
model->setSort(column, Qt::AscendingOrder);
model->select();
// 限制查询结果数量(大数据表)
model->setFilter("1=1 LIMIT 1000"); // 只获取前1000条记录
  • 对于大量数据操作,使用OnManualSubmit策略

  • 批量操作完成后一次性调用submitAll()

  • 使用setFilter()和setSort()减少数据传输量

  1. 常用信号和槽:
// 数据更改前的信号
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");
});
  1. 与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);
  1. 数据验证:
// 重写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() - 适合批量修改同一行的多个字段
Qt学习笔记
https://demo-firefly.netlify.app/posts/qt-learning-log/
作者
长琴
发布于
2025-11-18
许可协议
CC BY-NC-SA 4.0
最后更新于 2025-11-18,距今已过 3 天

部分内容可能已过时

评论区

目录

Loading ... - Loading ...
封面
Loading ...
Loading ...
0:00 / 0:00