Coding-QT-编程知识点

数据库相关

QLite数据库

1
2
3
4
5
6
7
8
9
db = QSqlDatabase::addDatabase("QSQLITE");  //添加数据库驱动
// 获取当前程序的工作目录
QString currentDir = QDir::currentPath();
// 拼接数据库文件名,例如 "mydatabase.db"
QString dbName = "mydatabase.db";
// 构建完整的数据库文件路径
QString dbFilePath = currentDir + "/" + dbName;

db.setDatabaseName(dbFilePath);

MySQL数据库

1
2
3
4
5
6
db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabaseName("mydatabase");
db.setHostName("localhost");
db.setPort(3306);
db.setUserName("username");
db.setPassword("password");

打开与检查数据库连接

1
2
3
4
5
if (!db.open()) {
qDebug() << "数据库连接失败";
} else {
qDebug() << "数据库连接成功";
}

SQL语句执行与查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  // 查询特定id的笔记内容
QSqlQuery query;
query.prepare("SELECT note FROM notes WHERE id = :id");
query.bindValue(":id", selectedId); // 绑定查询中的id占位符

// 创建notes表,如果不存在则创建
query.prepare("CREATE TABLE IF NOT EXISTS notes("
"date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "
"title VARCHAR(255) NOT NULL, "
"note TEXT, "
"id INTEGER PRIMARY KEY AUTOINCREMENT, " // 增加主键自动增长
"sort_order INTEGER)");

if (query.next()) { // 确保查询有结果再取值
int idOrder = query.value(0).toInt(); // 获取id
QString title = query.value(1).toString(); // 获取title
QString note = query.value(2).toString(); // 获取note
int sortOrder = query.value(3).toInt(); // 获取sort_order序号
}

// 查询所有笔记并按sort_order降序排列
QSqlQuery query2;
query2.prepare("SELECT id, title, note, sort_order FROM notes ORDER BY sort_order DESC");

// 更新笔记内容
QSqlQuery updateQuery;
updateQuery.prepare("UPDATE notes SET note = :newContent WHERE id = :id");
updateQuery.bindValue(":newContent", newText); // 绑定新的文本内容
updateQuery.bindValue(":id", currentId); // 基于当前选中标题更新对应的笔记内容

// 查询当前最大id(修正为查询最大sort_order)
QSqlQuery maxSortOrderQuery;
maxSortOrderQuery.prepare("SELECT MAX(sort_order) FROM notes");

// 插入新笔记记录
QSqlQuery insertQuery;
insertQuery.prepare("INSERT INTO notes (title, note, sort_order,id) VALUES (:title, :note, :sortOrder,:id)");
insertQuery.bindValue(":title", title);
insertQuery.bindValue(":note", ""); // 初始化笔记内容为空字符串
insertQuery.bindValue(":sortOrder", newSortOrder); // 使用新排序序号
insertQuery.bindValue(":id", newIdOrder); // 如果id是自增的,这行可以省略或注释掉

// 删除指定id的笔记记录
QSqlQuery deleteQuery;
deleteQuery.prepare("DELETE FROM notes WHERE id = :id");
deleteQuery.bindValue(":id", idToDelete);

// 统计记录数量
QSqlQuery checkEmptyQuery;
checkEmptyQuery.exec("SELECT COUNT(*) FROM notes");
checkEmptyQuery.next();
int rowCount = checkEmptyQuery.value(0).toInt();

心跳检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void MainWindow::ask_check()
{
// 使用成员变量或局部静态变量来存储定时器,确保其生命周期足够长
QTimer* heartbeatTimer = new QTimer(this); // 注意使用this指针作为父对象,以便于管理定时器的生命周期

connect(heartbeatTimer, &QTimer::timeout, this, [this]() {
QSqlQuery query(db);
if (query.exec("SELECT 1")) {
if (query.next()) {
ui->info_label->setStyleSheet("color: blue;");
qDebug() << "心跳检测 - 数据库连接正常";
}
} else {
ui->info_label->setStyleSheet("color: red;");
qDebug() << "心跳检测失败:" << query.lastError().text();
}
});
heartbeatTimer->start(60000); // 每60秒执行一次心跳检测
}

事件相关

概念

通过重写eventFilter方法,自定义对特定对象和事件类型的响应逻辑。例子:处理右键菜单和文本编辑器焦点变化,在合适的位置注册事件过滤器。通常在构造函数或初始化方法中完成此操作。

1
2
ui->listWidget->installEventFilter(this);
ui->textEdit->installEventFilter(this);

重写eventFilter方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
// 右键菜单处理
if (watched == ui->listWidget && event->type() == QEvent::ContextMenu) {
QContextMenuEvent *contextEvent = static_cast<QContextMenuEvent*>(event);

// 获取鼠标点击位置并转换为列表项索引
QModelIndex index = ui->listWidget->indexAt(contextEvent->pos());

// 如果索引有效,则弹出菜单
if (index.isValid()) {

rightClickMenu->exec(contextEvent->globalPos());

return true; // 消耗事件
}
}

// 文本编辑器焦点变化处理
if (watched == ui->textEdit) {
if (event->type() == QEvent::FocusIn) {
isTextEditFocused = true;
// 当textEdit获得焦点时,建立textChanged的信号槽连接
connect(ui->textEdit, &QTextEdit::textChanged, this, &MainWindow::onTextEditContentChanged);
}
else if (event->type() == QEvent::FocusOut)
{
isTextEditFocused = false;
// 当textEdit失去焦点时,断开textChanged的信号槽连接
disconnect(ui->textEdit, &QTextEdit::textChanged, this, &MainWindow::onTextEditContentChanged);
}
else if (event->type() & Qt::ControlModifier)
{
}
}
return QMainWindow::eventFilter(watched, event);
}