Qt制作天气预报+软件发布技巧

Hello!我是你们的老朋友--泽哥!这一期我们介绍如何使用QT的QNetWork的库进行高级网络编程开发!并且简述软件的包装与发布!咱们快开始吧!

(一)界面文件


下拉框采取二级联动的方式,下面左边是今天的天气,右边是明天的天气。点击开始搜索,程序发送网页请求,读取XML文件的数据,读进StringList中。

(二)主体文件

MainWindow.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_MainWindow.h"
#include<QNetworkAccessManager>
#include<QXmlStreamReader>
#include<QNetworkRequest>
#include<QNetworkReply>
#include<QStringList>
#include<QTextcodec>

class MainWindow : public QMainWindow
{
	Q_OBJECT

public:
	MainWindow(QWidget *parent = Q_NULLPTR);
	void Init();
	void showClear();

private slots:
	void replyFinished(QNetworkReply*);
	void ProvinceSlot(const QString &);
	void WeatherSlot();
private:
	Ui::MainWindow *ui;
	QStringList List;
	QNetworkAccessManager *caonima;
	int choose;//槽函数的选项
	QEventLoop eventLoop;
};
MainWindow.cpp

#include "MainWindow.h"
enum Tag
{
	INIT_Province = 1,INIT_CITY,CHANGE_CITY,QUERY_WEATHER
};
MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent),ui(new Ui::MainWindow)
{
	ui->setupUi(this);
	caonima = new QNetworkAccessManager(this);
	Init();//初始化界面
	connect(ui->comboBoxProvince, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(ProvinceSlot(const QString &)));
	connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(WeatherSlot()));
}
//---初始化界面的时候天气预报的默认值隐藏不见
void MainWindow::showClear()
{
	ui->labelImage1->clear();
	ui->labelImage2->clear();
	ui->labelTemperature->clear();
	ui->labelWeather->clear();
	ui->labelWind->clear();
//	ui->labelToday->clear();
	ui->labelTodayTips->clear();

	ui->labelImage3->clear();
	ui->labelImage4->clear();
	ui->labelTemperature_2->clear();
	ui->labelWeather_2->clear();
	ui->labelWind_2->clear();
//	ui->labelTomorrow->clear();
	ui->labelTomorrowTips->clear();
}
//---查询天气的槽函数
void MainWindow::WeatherSlot()
{
	choose = QUERY_WEATHER;
	QString CityName = ui->comboBoxCity->currentText();
	caonima->get(QNetworkRequest(QUrl("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName=" + CityName)));
	eventLoop.exec();
}
//---改变城市
void MainWindow::ProvinceSlot(const QString &ProvinceName)
{
	choose = CHANGE_CITY;
	caonima->get(QNetworkRequest(QUrl("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportCity?byProvinceName=" + ProvinceName)));
	eventLoop.exec();
}
//---网络请求槽函数
void MainWindow::replyFinished(QNetworkReply *reply)
{
	QTextCodec *codec = QTextCodec::codecForName("UTF-8");
	QString all = codec->toUnicode(reply->readAll());
	QXmlStreamReader reader(all);
	while (!reader.atEnd())
	{
		reader.readNext();
		if (reader.isStartElement())
		{
			if (reader.name() == "string")
			{
				List.append(reader.readElementText());
			}
		}
	}
	switch (choose)
	{
		case INIT_Province:
		{
			for (QStringList::const_iterator citer = List.constBegin(); citer != List.constEnd(); citer++)
			{
				ui->comboBoxProvince->addItem(*citer);
			}
			ui->comboBoxProvince->setCurrentIndex(0);//默认显示的是第一项(直辖市)

			break;
		}
		case INIT_CITY:
		{
			for (QStringList::const_iterator citer = List.constBegin(); citer != List.constEnd(); citer++)
			{
				QString str = citer->left(citer->indexOf(QChar(' ')));
				ui->comboBoxCity->addItem(str);
			}
			ui->comboBoxCity->setCurrentIndex(0);//默认在列表中显示的是第一项(基本上为省会城市)
			List.clear();
			break;
		}
		case CHANGE_CITY:
		{
			ui->comboBoxCity->clear();
			for (QStringList::const_iterator citer = List.constBegin(); citer != List.constEnd(); citer++)
			{
				QString str = citer->left(citer->indexOf(QChar(' ')));
				ui->comboBoxCity->addItem(str);
			}
			ui->comboBoxCity->setCurrentIndex(0);
			List.clear();
			break;
		}
		case QUERY_WEATHER:
		{
			if (List.count() < 23) { return; }
			QString strImage("rc//");
			ui->labelImage1->setPixmap(QPixmap(strImage + List[8]));
			ui->labelImage2->setPixmap(QPixmap(strImage + List[9]));
			ui->labelTemperature->setText(List[5]);
			ui->labelWind->setText(List[7]);
			ui->labelTodayTips->setText(List[10]);
			int tempIndex = List[11].indexOf(QChar(65292));
//			QString temp = List[11].left(List[11].indexOf(QChar(':')));
			QString temp = List[11].left(tempIndex);
			temp = temp.mid(6);
			ui->labelWeather->setText(temp);

			ui->labelImage3->setPixmap(QPixmap(strImage + List[15]));
			ui->labelImage4->setPixmap(QPixmap(strImage + List[16]));
			ui->labelTemperature_2->setText(List[12]);
			ui->labelWeather_2->setText(List[13]);
			ui->labelWind_2->setText(List[14]);
			ui->labelTomorrowTips->setText(List[22]);
			List.clear();
			break;
		}
	}
	reply->deleteLater();
}
//---页面初始化
void MainWindow::Init()
{
	//---初始化UI
	setWindowTitle(QString::fromLocal8Bit("天气预报"));
	setFixedSize(width(), height());
	setWindowIcon(QIcon(QPixmap("rc//a_0.gif")));
	Qt::WindowFlags flags = Qt::Dialog;
	flags |= Qt::WindowMinimizeButtonHint;
	flags |= Qt::WindowCloseButtonHint;
	setWindowFlags(flags);
	ui->labelLogo->setPixmap(QPixmap("rc//r_t1.gif"));
	ui->labelCity->setPixmap(QPixmap("rc//r_b.gif"));
	ui->labelTemperatureIcon->setPixmap(QPixmap("rc//tem1.gif"));
	ui->labelZiWaiXianIcon->setPixmap(QPixmap("rc//tem3.gif"));
	ui->labelDirectionIcon->setPixmap(QPixmap("rc//tem2.gif"));
	ui->labelTemperatureIcon_2->setPixmap(QPixmap("rc//tem1.gif"));
	ui->labelZiWaiXianIcon_2->setPixmap(QPixmap("rc//tem3.gif"));
	ui->labelDirection_2->setPixmap(QPixmap("rc//tem2.gif"));
	showClear();


	choose = INIT_Province;//初始化省份列表(代号:1)
	caonima->get(QNetworkRequest(QUrl("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportProvince?")));//发送页面请求
	connect(caonima, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
	//---局部事件循环,当replyFinished完成后,caonima发送finished信号,才开始exec()后面的代码
//	QEventLoop eventLoop;
	connect(caonima, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
	eventLoop.exec();

	choose = INIT_CITY;//初始化城市列表(代号:2)
	QString City = List.at(0);//默认省份列表第一项(直辖市)为默认省份
	List.clear();
	caonima->get(QNetworkRequest(QUrl("http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportCity?byProvinceName=" + City)));//发送请求

	//---局部事件循环
	connect(caonima, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
	eventLoop.exec();
}
这个项目有以下几点需要注意一下:

1.一个项目只需开一个QNetworkAccessManager的对象即可,在构造函数中对其分配内存(new一个~)

2.enum枚举型是个好东西,基本上用它设置多个常量可以取代const和#define

3.XML的读取请戳这里QXmlStreamReader的用法详解

4.引入局部事件循环的方法,请戳这里!

这个xml读取到底是个啥流程呢?请看下面:执行QNetworkAccessManager的对象*caonima的方法get(URL),向服务器端发送XML文件请求,接收到服务器方的http报文之后,caonima会发送finished(QNetworkReply)的信号,执行对应的槽函数replyFinished(QNetworkReply),对http报文中的xml进行解析,读取数据,之后caonima发送QNetworkAccessManager::finished的信号,执行对应的槽函数quit(),执行eventLoop.exec()之后的程序。为啥这么做呢,因为网络请求的速度是很慢的,是异步的程序,为了防止一些变量还没等XML文件处理完就被别的程序段修改,咱们强制性的将异步的SML请求读取变为顺序执行。ok,讲到这里!





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值