应用层开发
# 10.应用层开发
- 10.1 网络请求
- 10.1.1 XMLHttpRequest
- 10.1.2 QNetworkAccessManager
- 10.1.3 C++网络库
- 10.2 数据存储
- 10.2.1 本地存储实现
- 10.2.2 LocalStorage
- 10.2.3 Settings
- 10.2.4 C++扩展文件
- 10.2.5 C++存储库
# 10.1 网络请求
在 Qt Quick (QML) 中,可以通过 XMLHttpRequest 或 Qt 提供的 QNetworkAccessManager 进行网络请求。
| 方法 | 优点 | 缺点 |
|---|---|---|
XMLHttpRequest | 简单易用,无需 C++ 代码 | 功能有限,不适合复杂场景 |
QNetworkAccessManager | 功能强大,适合复杂网络请求 | 需要编写 C++ 代码并注册到 QML |
# 10.1.1 XMLHttpRequest
使用XMLHttpRequest 是 QML 内置的 JavaScript 对象,用于发送 HTTP 请求。
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://jsonplaceholder.typicode.com/posts/1");
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
resultText.text = "Response: " + xhr.responseText;
} else {
resultText.text = "Error: " + xhr.status;
}
}
};
xhr.send();
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 10.1.2 QNetworkAccessManager
QNetworkAccessManager 是 Qt 提供的 C++ 类,功能更强大,适合复杂的网络请求。可以通过 C++ 扩展 QML 来使用它。
- 定义 C++ 网络请求类:使用
QNetworkAccessManager发送请求。通过信号和槽处理响应。 - 注册 C++ 类到 QML: 使用
qmlRegisterType将 C++ 类注册为 QML 类型。 - 在 QML 中使用 C++ 类:实例化 C++ 类并调用其方法。
1. 头文件(NetworkManager.h)
#ifndef NETWORKMANAGER_H
#define NETWORKMANAGER_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
class NetworkManager : public QObject {
Q_OBJECT
public:
explicit NetworkManager(QObject *parent = nullptr);
// 发送 GET 请求
Q_INVOKABLE void get(const QString &url);
signals:
// 请求完成信号
void finished(const QString &response);
void error(const QString &message);
private slots:
// 处理请求完成
void onFinished(QNetworkReply *reply);
private:
QNetworkAccessManager *m_manager;
};
#endif // NETWORKMANAGER_H
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
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
2. 实现文件(NetworkManager.cpp)
#include "NetworkManager.h"
#include <QDebug>
NetworkManager::NetworkManager(QObject *parent) : QObject(parent) {
m_manager = new QNetworkAccessManager(this);
}
void NetworkManager::get(const QString &url) {
QNetworkRequest request;
request.setUrl(QUrl(url));
QNetworkReply *reply = m_manager->get(request);
connect(reply, &QNetworkReply::finished, this, [this, reply]() { onFinished(reply); });
}
void NetworkManager::onFinished(QNetworkReply *reply) {
if (reply->error() == QNetworkReply::NoError) {
QString response = reply->readAll();
emit finished(response);
} else {
emit error(reply->errorString());
}
reply->deleteLater();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
3. 注册到 QML(main.cpp)
#include "NetworkManager.h" // 包含网络请求类头文件
int main(int argc, char *argv[]) {
// 注册 C++ 类到 QML
qmlRegisterType<NetworkManager>("com.example.network", 1, 0, "NetworkManager");
return app.exec();
}
1
2
3
4
5
6
7
2
3
4
5
6
7
4. 在 QML 中使用
import QtQuick 2.15
import QtQuick.Controls 2.15
import com.example.network 1.0 // 导入 C++ 类
ApplicationWindow {
visible: true
width: 800
height: 600
title: "Network Request with QNetworkAccessManager"
Column {
anchors.centerIn: parent
spacing: 10
// 显示请求结果
Text {
id: resultText
text: "Click the button to fetch data"
font.pixelSize: 20
}
// 发送请求的按钮
Button {
text: "Fetch Data"
onClicked: networkManager.get("https://jsonplaceholder.typicode.com/posts/1")
}
}
// 实例化 C++ 类
NetworkManager {
id: networkManager
onFinished: (response) => resultText.text = "Response: " + response
onError: (message) => resultText.text = "Error: " + message
}
}
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
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
# 10.1.3 C++网络库
# 10.2 数据存储
# 10.2.1 本地存储实现
| 方法 | 优点 | 缺点 |
|---|---|---|
LocalStorage | 轻量级,适合结构化数据 | 仅支持 SQLite 数据库 |
Settings | 简单易用,适合键值对存储 | 功能有限,不适合复杂数据 |
| C++ 文件操作 | 功能强大,适合复杂文件操作 | 需要编写 C++ 代码并注册到 QML |
# 10.2.2 LocalStorage
LocalStorage 是 QML 内置的轻量级 SQLite 数据库,适合存储结构化数据。示例代码
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.LocalStorage 2.15
ApplicationWindow {
visible: true
width: 800
height: 600
title: "LocalStorage Example"
// 初始化数据库
Component.onCompleted: {
var db = LocalStorage.openDatabaseSync("MyAppDB", "1.0", "Local Storage Example", 1000000);
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Data(key TEXT UNIQUE, value TEXT)');
});
}
Column {
anchors.centerIn: parent
spacing: 10
// 显示存储的值
Text {
id: storedValue
text: "No value stored"
font.pixelSize: 20
}
// 输入框
TextField {
id: inputField
placeholderText: "Enter a value"
}
// 保存按钮
Button {
text: "Save"
onClicked: {
var db = LocalStorage.openDatabaseSync("MyAppDB", "1.0", "Local Storage Example", 1000000);
db.transaction(function(tx) {
tx.executeSql('INSERT OR REPLACE INTO Data VALUES(?, ?)', ["myKey", inputField.text]);
});
storedValue.text = "Stored: " + inputField.text;
}
}
// 加载按钮
Button {
text: "Load"
onClicked: {
var db = LocalStorage.openDatabaseSync("MyAppDB", "1.0", "Local Storage Example", 1000000);
db.transaction(function(tx) {
var result = tx.executeSql('SELECT value FROM Data WHERE key = ?', ["myKey"]);
if (result.rows.length > 0) {
storedValue.text = "Loaded: " + result.rows[0].value;
} else {
storedValue.text = "No value found";
}
});
}
}
}
}
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
53
54
55
56
57
58
59
60
61
62
63
64
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
53
54
55
56
57
58
59
60
61
62
63
64
# 10.2.3 Settings
Settings 是 Qt 提供的用于存储应用程序设置的类,适合存储简单的键值对。示例代码
import QtQuick 2.15
import QtQuick.Controls 2.15
import Qt.labs.settings 1.1
ApplicationWindow {
visible: true
width: 800
height: 600
title: "Settings Example"
// 使用 Settings 存储数据
Settings {
id: appSettings
property string storedValue: ""
}
Column {
anchors.centerIn: parent
spacing: 10
// 显示存储的值
Text {
id: storedValueText
text: "Stored Value: " + appSettings.storedValue
font.pixelSize: 20
}
// 输入框
TextField {
id: inputField
placeholderText: "Enter a value"
}
// 保存按钮
Button {
text: "Save"
onClicked: {
appSettings.storedValue = inputField.text;
storedValueText.text = "Stored Value: " + inputField.text;
}
}
}
}
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
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
# 10.2.4 C++扩展文件
如果需要更复杂的文件操作,可以通过 C++ 扩展 QML 来实现。步骤
- 定义 C++ 文件操作类:使用
QFile和QTextStream读写文件。 - 注册 C++ 类到 QML: 使用
qmlRegisterType将 C++ 类注册为 QML 类型。 - 在 QML 中使用 C++ 类: 实例化 C++ 类并调用其方法。
1. 头文件(FileManager.h)
#ifndef FILEMANAGER_H
#define FILEMANAGER_H
#include <QObject>
#include <QFile>
#include <QTextStream>
class FileManager : public QObject {
Q_OBJECT
public:
explicit FileManager(QObject *parent = nullptr);
// 写入文件
Q_INVOKABLE bool writeFile(const QString &filePath, const QString &content);
// 读取文件
Q_INVOKABLE QString readFile(const QString &filePath);
};
#endif // FILEMANAGER_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2. 实现文件(FileManager.cpp)
#include "FileManager.h"
#include <QDebug>
FileManager::FileManager(QObject *parent) : QObject(parent) {}
bool FileManager::writeFile(const QString &filePath, const QString &content) {
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qWarning() << "Failed to open file for writing:" << filePath;
return false;
}
QTextStream out(&file);
out << content;
file.close();
return true;
}
QString FileManager::readFile(const QString &filePath) {
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open file for reading:" << filePath;
return "";
}
QTextStream in(&file);
QString content = in.readAll();
file.close();
return content;
}
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
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
3. 注册到 QML(main.cpp)
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "FileManager.h" // 包含文件操作类头文件
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
// 注册 C++ 类到 QML
qmlRegisterType<FileManager>("com.example.filemanager", 1, 0, "FileManager");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4. 在 QML 中使用(main.qml)
import QtQuick 2.15
import QtQuick.Controls 2.15
import com.example.filemanager 1.0 // 导入 C++ 类
ApplicationWindow {
visible: true
width: 800
height: 600
title: "File Storage Example"
Column {
anchors.centerIn: parent
spacing: 10
// 显示文件内容
Text {
id: fileContent
text: "No content loaded"
font.pixelSize: 20
}
// 输入框
TextField {
id: inputField
placeholderText: "Enter content to save"
}
// 保存按钮
Button {
text: "Save to File"
onClicked: {
fileManager.writeFile("example.txt", inputField.text);
fileContent.text = "Saved: " + inputField.text;
}
}
// 加载按钮
Button {
text: "Load from File"
onClicked: {
fileContent.text = "Loaded: " + fileManager.readFile("example.txt");
}
}
}
// 实例化 C++ 类
FileManager {
id: fileManager
}
}
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
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
# 10.2.5 C++存储库
上次更新: 2026/06/10, 11:13:41