Qt + HarmonyOS PC应用每日早报应用开发实战
Qt + HarmonyOS 每日早报应用开发实战
📱 项目简介
本文将详细介绍如何使用 Qt 框架在 HarmonyOS 平台上开发一款每日早报应用。该应用通过网络请求获取每日新闻数据,并以美观的界面展示给用户,是学习 Qt + HarmonyOS 开发的绝佳实战案例。
项目地址: https://gitcode.com/nutpi/QtDailyMorningPost
效果:

✨ 主要功能
- 📰 获取并展示每日早报新闻(15条)
- 🔄 支持手动刷新功能
- 💬 显示每日微语
- 🎨 现代化的 Material Design 风格界面
- ⚡ 异步网络请求,不阻塞UI
- 🛡️ 完善的错误处理机制
🛠️ 技术栈
- 开发框架: Qt 5.x for HarmonyOS
- 编程语言: C++ 17 / QML
- 网络库: Qt Network (QNetworkAccessManager)
- 数据格式: JSON (Qt JSON)
- 界面: QML + Qt Quick Controls 2
- 构建工具: CMake
- 目标平台: HarmonyOS (OpenHarmony)
🏗️ 项目架构
qtdemo-1/
├── entry/src/main/
│ ├── cpp/
│ │ ├── main.cpp # 应用入口
│ │ ├── main.qml # 主界面
│ │ ├── newsmanager.h # 新闻管理器头文件
│ │ ├── newsmanager.cpp # 新闻管理器实现
│ │ └── CMakeLists.txt # 构建配置
│ ├── module.json5 # 模块配置(权限)
│ └── resources/ # 资源文件
📝 核心功能实现
1. NewsManager - 网络请求与数据管理
NewsManager 是整个应用的核心类,负责网络请求、数据解析和状态管理。
1.1 类定义 (newsmanager.h)
class NewsManager : public QObject
{
Q_OBJECT
// 定义属性,可在QML中直接访问
Q_PROPERTY(QString date READ date NOTIFY dateChanged)
Q_PROPERTY(QStringList newsList READ newsList NOTIFY newsListChanged)
Q_PROPERTY(QString weiyu READ weiyu NOTIFY weiyuChanged)
Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
Q_PROPERTY(QString errorMessage READ errorMessage NOTIFY errorMessageChanged)
public:
explicit NewsManager(QObject *parent = nullptr);
// Getter 方法
QString date() const { return m_date; }
QStringList newsList() const { return m_newsList; }
QString weiyu() const { return m_weiyu; }
bool loading() const { return m_loading; }
QString errorMessage() const { return m_errorMessage; }
public slots:
void fetchNews(); // 获取新闻的槽函数,QML可调用
signals:
// 信号,数据变化时通知QML更新界面
void dateChanged();
void newsListChanged();
void weiyuChanged();
void loadingChanged();
void errorMessageChanged();
private slots:
void onNetworkReply(QNetworkReply *reply);
private:
void parseJsonResponse(const QByteArray &data);
QNetworkAccessManager *m_networkManager;
QString m_date;
QStringList m_newsList;
QString m_weiyu;
bool m_loading;
QString m_errorMessage;
};
设计要点:
- 使用
Q_PROPERTY将 C++ 属性暴露给 QML - 使用信号-槽机制实现数据变化通知
- 所有需要在 QML 中调用的方法都声明为
public slots
1.2 网络请求实现 (newsmanager.cpp)
void NewsManager::fetchNews()
{
setLoading(true);
setErrorMessage("");
// 使用HTTP协议(Qt for HarmonyOS 不支持HTTPS)
QUrl url("http://v3.alapi.cn/api/zaobao");
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
// 设置10秒超时
request.setTransferTimeout(10000);
// 构建POST参数
QUrlQuery params;
params.addQueryItem("token", "ycd0krwbhl5v2w6iafblj94y5vzqdj");
params.addQueryItem("format", "json");
QByteArray postData = params.toString(QUrl::FullyEncoded).toUtf8();
qDebug() << "发送早报请求到:" << url.toString();
m_networkManager->post(request, postData);
}
技术要点:
- Qt for HarmonyOS 不支持 SSL,必须使用 HTTP 协议
- 使用 POST 方法发送请求
- 通过
QUrlQuery构建表单数据 - 设置合理的超时时间避免长时间等待
1.3 数据解析
void NewsManager::parseJsonResponse(const QByteArray &data)
{
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
QJsonObject root = doc.object();
if (root["code"].toInt() != 200) {
setErrorMessage("API错误: " + root["msg"].toString());
return;
}
QJsonObject dataObj = root["data"].toObject();
// 解析日期
m_date = dataObj["date"].toString();
emit dateChanged();
// 解析新闻列表
QJsonArray newsArray = dataObj["news"].toArray();
m_newsList.clear();
for (int i = 0; i < newsArray.size(); ++i) {
m_newsList.append(newsArray[i].toString());
}
emit newsListChanged();
// 解析微语
m_weiyu = dataObj["weiyu"].toString();
emit weiyuChanged();
}
关键点:
- 使用 Qt JSON 模块解析 JSON 数据
- 每次数据更新后发送相应的信号通知 QML
- 完善的错误处理
2. QML 界面实现
2.1 主窗口布局
Window {
width: 800
height: 1200
visible: true
title: "每日早报 - Qt for 鸿蒙"
Rectangle {
anchors.fill: parent
gradient: Gradient {
GradientStop { position: 0.0; color: "#e3f2fd" }
GradientStop { position: 1.0; color: "#bbdefb" }
}
// 标题栏
Rectangle { ... }
// 刷新按钮
Button { ... }
// 新闻列表
ScrollView { ... }
// 微语区域
Rectangle { ... }
}
}
2.2 新闻列表实现
ListView {
id: newsListView
width: parent.width
spacing: 15
model: newsManager.newsList // 直接绑定C++数据
delegate: Rectangle {
width: newsListView.width
height: Math.max(newsText.implicitHeight + 40, 60)
color: "#ffffff"
radius: 12
border.color: "#90caf9"
border.width: 2
Text {
id: newsText
text: modelData
font.pixelSize: 26
color: "#212121"
anchors.fill: parent
anchors.margins: 20
wrapMode: Text.Wrap
lineHeight: 1.4
}
}
}
设计亮点:
- 使用
ListView实现高性能滚动列表 - 卡片式设计,每条新闻独立显示
- 自动计算高度适应内容
- Material Design 配色方案
2.3 交互功能
Button {
text: newsManager.loading ? "加载中..." : "🔄 刷新"
enabled: !newsManager.loading
onClicked: {
newsManager.fetchNews() // 调用C++方法
}
}
// 自动加载
Component.onCompleted: {
newsManager.fetchNews()
}
3. C++ 与 QML 数据绑定
在 main.cpp 中注册 C++ 对象到 QML 上下文:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// 创建NewsManager实例
NewsManager newsManager;
// 注册到QML上下文,名称为"newsManager"
engine.rootContext()->setContextProperty("newsManager", &newsManager);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
数据流程:
- QML 调用
newsManager.fetchNews() - C++ 发起网络请求
- 数据返回后解析并更新成员变量
- 发送
newsListChanged()等信号 - QML 界面自动更新显示
🔧 配置与权限
1. CMakeLists.txt 配置
# 添加源文件
add_library(entry SHARED
main.cpp
newsmanager.cpp
newsmanager.h
qml.qrc
)
# 链接Qt Network模块
target_link_libraries(entry PRIVATE
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Qml
Qt${QT_VERSION_MAJOR}::Quick
# ... 其他模块
)
2. 网络权限配置
在 module.json5 中添加网络权限:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}
在 string.json 中添加权限说明:
{
"string": [
{
"name": "internet_permission_reason",
"value": "需要网络权限来获取每日早报数据"
}
]
}
🐛 问题与解决方案
问题1: Protocol ‘https’ is unknown
原因: Qt for HarmonyOS 版本未编译 SSL/TLS 支持
解决方案: 将 API 请求协议从 HTTPS 改为 HTTP
// 错误:QUrl url("https://v3.alapi.cn/api/zaobao");
// 正确:
QUrl url("http://v3.alapi.cn/api/zaobao");
问题2: Host not found
原因: 应用缺少网络权限
解决方案: 在 module.json5 中添加 ohos.permission.INTERNET 权限
问题3: 新闻列表只显示边框不显示文字
原因:
- ListView delegate 高度计算问题
- layer.effect 在某些 Qt 版本有兼容性问题
解决方案:
// 使用 implicitHeight 计算高度
height: Math.max(newsText.implicitHeight + 40, 60)
// 移除可能有问题的 layer.effect
// layer.enabled: true // 删除此行
问题4: 编译错误 - QSslError incomplete type
原因: 引入了不支持的 SSL 相关头文件
解决方案: 从代码中移除所有 SSL 相关的引用
// 删除:#include <QSslSocket>
// 删除:#include <QSslError>
// 删除:#include <QSslConfiguration>
🎯 优化技巧
1. 性能优化
- 使用
ListView而不是Repeater,支持虚拟化滚动 - 网络请求使用异步方式,不阻塞 UI 线程
- 合理设置超时时间避免无限等待
2. 用户体验优化
- 添加加载状态指示器
- 显示友好的错误信息
- 支持下拉刷新
- 自动加载初始数据
3. 调试技巧
添加详细的日志输出:
qDebug() << "收到的原始数据:" << data;
qDebug() << "API返回code:" << code;
qDebug() << "新闻数组大小:" << newsArray.size();
📊 效果展示
应用运行效果:
- ✅ 顶部蓝色标题栏显示"每日早报"和日期
- ✅ 中间区域滚动显示15条新闻,每条新闻在白色卡片中
- ✅ 底部橙色区域显示每日微语
- ✅ 点击刷新按钮可重新获取数据
- ✅ 加载过程中显示"加载中…"状态
🎓 学习要点
通过这个项目,你将学到:
- Qt Network 编程: HTTP POST 请求、数据解析
- QML 界面开发: ListView、ScrollView、Material Design
- C++ 与 QML 交互: Q_PROPERTY、信号-槽、上下文注册
- HarmonyOS 开发: 权限配置、模块管理
- JSON 数据处理: Qt JSON API 的使用
- 异步编程: 网络请求的异步处理
- 错误处理: 网络错误、解析错误的处理机制
🚀 扩展方向
基于现有功能,你可以继续扩展:
- 添加缓存机制: 使用 SQLite 存储历史数据
- 支持图片显示: 显示早报头图
- 分享功能: 分享新闻到社交平台
- 收藏功能: 收藏感兴趣的新闻
- 历史记录: 查看往期早报
- 推送通知: 每天定时推送早报
- 主题切换: 支持深色模式
- 字体设置: 可调节字体大小
📚 参考资源
💡 总结
本文通过一个完整的每日早报应用案例,展示了如何使用 Qt 框架在 HarmonyOS 平台上开发网络应用。从网络请求、数据解析到界面展示,涵盖了移动应用开发的核心技能。
项目的关键技术点包括:
- Qt Network 模块的使用
- C++ 与 QML 的数据绑定
- Qt JSON API 的应用
- HarmonyOS 权限配置
- Material Design 界面设计
希望这个案例能帮助你快速上手 Qt + HarmonyOS 开发!
作者: 坚果派
日期: 2025-11-09
项目地址: https://gitcode.com/nutpi/QtDailyMorningPost
许可证: MIT
如果觉得这篇文章对你有帮助,欢迎 Star ⭐ 支持!
更多推荐

所有评论(0)