项目名称:基于Qt框架的跨平台天气预报应用程序
项目名称:基于Qt框架的跨平台天气预报应用程序
项目描述:
独立设计并开发了一款跨平台的桌面天气预报应用。该程序通过调用第三方天气API获取实时数据,使用Qt强大的界面库构建了直观、美观的用户界面,并实现了无边框窗口、自定义拖拽、右键菜单等增强型用户体验功能。
技术栈:
开发语言/框架: C++, Qt
网络编程: QNetworkAccessManager, HTTP GET请求, JSON数据解析
UI/UX: 无边框窗口自定义、鼠标事件处理、自定义右键菜单、布局管理
数据格式: JSON
核心功能与实现亮点:
- 实时天气数据获取与解析
- 使用 QNetworkAccessManager发起HTTP请求,调用心知天气API接口获取结构化天气数据
- 利用Qt内置的 QJsonDocument, QJsonObject, QJsonArray高效解析复杂的JSON响应数据
- 实现了完整的网络请求错误处理机制,确保应用稳定性
优雅的用户交互体验
1. 自定义无边框窗口: 通过 setWindowFlag(Qt::FramelessWindowHint)实现,并重写 mousePressEvent和 mouseMoveEvent来支持窗口拖拽移动
2. 上下文菜单: 实现右键菜单(QMenu)提供快捷退出功能,并应用了QSS样式美化
- 数据可视化: 清晰展示了多项天气指标(温度、湿度、空气质量、风力、PM2.5、感冒指数)和未来五天预报
软件工程实践
- 采用面向对象设计,模块化结构清晰(网络请求、数据处理、UI渲染分离)
- 实现了资源管理(如图标资源)、内存管理(智能指针使用)和异常处理
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMouseEvent>#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QMessageBox>#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setWindowFlag(Qt::FramelessWindowHint);menuQuit = new QMenu(this);menuQuit-> setStyleSheet("QMenu::item{color: white; border-radius: 10px}");QAction *quitAct = new QAction(QIcon(":/icon/power.png"), tr("&Quit..."), this);menuQuit->addAction(quitAct);connect(menuQuit, &QMenu::triggered, this, [=]{this->close();});QNetworkAccessManager *manager = new QNetworkAccessManager(this);reply = manager->get(QNetworkRequest(QUrl("http://v1.yiketianqi.com/free/week?appid=74313119&appsecret=peboEb8d&unescape=1")));connect(reply, &QNetworkReply::finished, this, &Widget::readHttpReply);
}/*
QNetworkAccessManager *manager = new QNetworkAccessManager(this);connect(manager, &QNetworkAccessManager::finished,this, &MyClass::replyFinished);manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
*/Widget::~Widget()
{delete ui;
}void Widget::readHttpReply()
{int reqCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();if (reply->error() == QNetworkReply::NoError && reqCode == 200){
// qDebug() << QString::fromUtf8(reply->readAll()) << endl;QJsonDocument jsondoc = QJsonDocument::fromJson(reply->readAll());qDebug() << jsondoc["city"].toString()<< endl;} else {QMessageBox msg;msg.setWindowTitle("警告");msg.setText("请求失败");msg.setStyleSheet("background-color:white");msg.setStandardButtons(QMessageBox::Ok);msg.setParent(this);msg.exec();}
}/*
QMenu menu;QAction *at = actions[0]; // Assumes actions is not emptyforeach (QAction *a, actions)menu.addAction(a);menu.exec(pos, at);
*/void Widget::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::RightButton)menuQuit->exec(QCursor::pos());if (event->button() == Qt::LeftButton){offset = event->pos();
// QPoint currentPos = event->globalPos();
// this->setGeometry(currentPos.x()-offset.x(), currentPos.y()-offset.y(), this->width(), this->height());}
}void Widget::mouseMoveEvent(QMouseEvent *event)
{this->move(event->globalPos()-offset);
}#ifndef WIDGET_H
#define WIDGET_H#include <QMenu>
#include <QWidget>
#include <qnetworkreply.h>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:void readHttpReply();protected:void mousePressEvent(QMouseEvent *event) ;void mouseMoveEvent(QMouseEvent *event);private:Ui::Widget *ui;QMenu *menuQuit;QPoint offset;QNetworkReply *reply;
};
#endif // WIDGET_H
项目成果:
- 成功实现了一个稳定、响应迅速的天气应用,界面简洁美观,交互流畅
- 掌握了Qt框架下网络请求、数据解析与GUI开发的全栈技能
- 深入理解了异步编程模型(信号与槽机制)和事件处理机制
💡 面试时可能的深入提问及回答建议:
- Q: 为什么选择Qt框架?
A: Qt的信号与槽机制非常适合处理异步操作(如网络请求),其跨平台特性强,一次编写可在Windows、Linux、macOS上运行,并且提供了丰富的GUI组件和强大的自定义能力。
- Q: 如何处理网络请求的异步响应?
A: 我使用了Qt的信号与槽机制。当 QNetworkReply的 finished()信号发出时,会连接到自定义的 readHttpReply()槽函数进行数据处理,这样保证了UI线程不会被阻塞。
- Q: 项目中遇到的最大挑战是什么?
A: 一是JSON数据结构的解析,需要准确把握API返回的嵌套结构;二是无边框窗口的自定义拖动实现,需要精确处理鼠标事件。通过查阅Qt文档和调试,我很好地解决了这些问题。
- Q: 如果API请求失败,程序如何应对?
A: 我检查了 QNetworkReply的 error()和HTTP状态码。如果请求失败,会通过 QMessageBox向用户弹出友好的错误提示,而不是让程序崩溃或无响应。