能够切换中国国内的所有省、城市、县,使用的是QQ安装目录下的I18N/2052/LocList.xml文件。文件也可以在日历天气的可执行程序的data目录下下载。
关于天气系统的完整说明详见:Qt实战小工具 – 日丽天气V1.0
程序运行效果如下:
XML文件中的内容如下:
<CountryRegion Name="中国" Code="1">
<State Name="北京" Code="11">
<City Name="东城" Code="1" />
<City Name="西城" Code="2" />
<City Name="朝阳" Code="5" />
<City Name="丰台" Code="6" />
<City Name="石景山" Code="7" />
<City Name="海淀" Code="8" />
<City Name="门头沟" Code="9" />
<City Name="房山" Code="11" />
<City Name="通州" Code="12" />
<City Name="顺义" Code="13" />
<City Name="昌平" Code="21" />
<City Name="大兴" Code="24" />
<City Name="平谷" Code="26" />
<City Name="怀柔" Code="27" />
<City Name="密云" Code="28" />
<City Name="延庆" Code="29" />
</State>
<State Name="天津" Code="12">
<City Name="和平" Code="1" />
<City Name="河东" Code="2" />
<City Name="河西" Code="3" />
<City Name="南开" Code="4" />
<City Name="河北" Code="5" />
<City Name="红桥" Code="6" />
<City Name="滨海新区" Code="26" />
<City Name="东丽" Code="10" />
<City Name="西青" Code="11" />
<City Name="津南" Code="12" />
<City Name="北辰" Code="13" />
<City Name="宁河" Code="21" />
<City Name="武清" Code="22" />
<City Name="静海" Code="23" />
<City Name="宝坻" Code="24" />
<City Name="蓟县" Code="25" />
</State>
<State Name="河北" Code="13">
<City Name="石家庄" Code="1">
<Region Name="长安区" Code="2" />
<Region Name="桥东区" Code="3" />
<Region Name="桥西区" Code="4" />
<Region Name="新华区" Code="5" />
<Region Name="井陉矿区" Code="7" />
<Region Name="裕华区" Code="8" />
<Region Name="井陉县" Code="21" />
<Region Name="正定县" Code="23" />
<Region Name="栾城县" Code="24" />
<Region Name="行唐县" Code="25" />
<Region Name="灵寿县" Code="26" />
<Region Name="高邑县" Code="27" />
<Region Name="深泽县" Code="28" />
<Region Name="赞皇县" Code="29" />
<Region Name="无极县" Code="30" />
<Region Name="平山县" Code="31" />
<Region Name="元氏县" Code="32" />
<Region Name="赵县" Code="33" />
<Region Name="辛集市" Code="81" />
<Region Name="藁城市" Code="82" />
<Region Name="晋州市" Code="83" />
<Region Name="新乐市" Code="84" />
<Region Name="鹿泉市" Code="85" />
</City>
</State>
......
</CountryRegion >
程序解析XML文件部分代码如下:
UIChinaCity.h 文件
#ifndef UICHINACITY_H
#define UICHINACITY_H
#include <QObject>
#include <QMap>
class UIChinaCity : public QObject
{
Q_OBJECT
public:
UIChinaCity(QObject *parent = nullptr);
~UIChinaCity();
struct CityInfo
{
QString cityName; // 城市名字
QList<QString> regionName; // 城市下的区的名字
};
// 获取所有的省份
QList<QString> getProvinceName(void);
// 获取某个省下的所有的城市
QList<QString> getCitysName(QString);
// 获取某个省下的某个市下的所有的县
QList<QString> getRegionsName(QString, QString);
private:
// 解析城市列表
void disposeCityList(void);
QMap<QString, QList<CityInfo>> m_ChinaCityInfo;
};
#endif
UIChinaCity.cpp文件
#ifndef WEATHER_CITY_CHANGE_WINDOW_H
#define WEATHER_CITY_CHANGE_WINDOW_H
#include "UIBase/UIBaseWindow.h"
#include <QComboBox>
#include <QPushButton>
#include <QLabel>
#include "UIBase/UIChinaCity.h"
class WeatherCityChangeWindow : public UIBaseWindow
{
Q_OBJECT
public:
WeatherCityChangeWindow(QWidget *parent = nullptr);
~WeatherCityChangeWindow();
private:
QComboBox *m_StateComboBox = nullptr;
QComboBox *m_CityComboBox = nullptr;
QComboBox *m_RegionComboBox = nullptr;
QLabel *m_StateLabel;
QLabel *m_CityLabel;
QLabel *m_RegionLabel;
QPushButton *m_OKButton;
QPushButton *m_CannelButton;
UIChinaCity *chinaCityManager = nullptr;
private slots:
void onStateComboBoxIndexChanged(int);
void onCityComboBoxIndexChanged(int);
void onOKClicked(void);
void onCannelClicked(void);
signals:
void changeCity(void);
};
#endif
WeatherCityChangeWindow.cpp文件
#include "WeatherCityChangeWindow.h"
#include <QVBoxLayout>
#include "WeatherApi/WeatherInterface.h"
#include "UIBase/UIGlobalTool.h"
#include <QListView>
WeatherCityChangeWindow::WeatherCityChangeWindow(QWidget *parent)
:UIBaseWindow(parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addSpacing(30);
chinaCityManager = new UIChinaCity(this);
QWidget *mainWidget = new QWidget(this);
QVBoxLayout *bottomLayout = new QVBoxLayout(mainWidget);
// 初始化下拉Tag
QHBoxLayout *tagLabelLayout = new QHBoxLayout;
m_StateLabel = new QLabel("省/直辖市");
m_CityLabel = new QLabel("城市/直辖市区");
m_RegionLabel = new QLabel("区/县");
tagLabelLayout->addWidget(m_StateLabel, 0, Qt::AlignCenter);
tagLabelLayout->addWidget(m_CityLabel, 0, Qt::AlignCenter);
tagLabelLayout->addWidget(m_RegionLabel, 0, Qt::AlignCenter);
// 初始化下拉按钮
QHBoxLayout *comboLayout = new QHBoxLayout;
m_StateComboBox = new QComboBox;
m_StateComboBox->addItems(chinaCityManager->getProvinceName());
m_StateComboBox->setView(new QListView(m_StateComboBox));
comboLayout->addWidget(m_StateComboBox);
m_CityComboBox = new QComboBox;
comboLayout->addWidget(m_CityComboBox);
m_CityComboBox->setView(new QListView(m_CityComboBox));
m_RegionComboBox = new QComboBox;
m_RegionComboBox->setView(new QListView(m_RegionComboBox));
g_GlobalTool->addShadowEffect(m_StateComboBox);
g_GlobalTool->addShadowEffect(m_CityComboBox);
g_GlobalTool->addShadowEffect(m_RegionComboBox);
comboLayout->addWidget(m_RegionComboBox);
// 初始化按钮
QHBoxLayout *buttonLayout = new QHBoxLayout;
m_OKButton = new QPushButton("确定");
m_CannelButton = new QPushButton("取消");
buttonLayout->addStretch();
buttonLayout->addWidget(m_OKButton);
buttonLayout->addWidget(m_CannelButton);
g_GlobalTool->addShadowEffect(m_OKButton);
g_GlobalTool->addShadowEffect(m_CannelButton);
// 添加布局
bottomLayout->addLayout(tagLabelLayout);
bottomLayout->addLayout(comboLayout);
bottomLayout->addStretch();
bottomLayout->addLayout(buttonLayout);
layout->addWidget(mainWidget);
this->resize(500, 200);
// 建立信号和槽的连接
QObject::connect(m_StateComboBox, SIGNAL(currentIndexChanged(int)), \
this, SLOT(onStateComboBoxIndexChanged(int)));
QObject::connect(m_CityComboBox, SIGNAL(currentIndexChanged(int)), \
this, SLOT(onCityComboBoxIndexChanged(int)));
QObject::connect(m_OKButton, SIGNAL(clicked(bool)), this, SLOT(onOKClicked()));
QObject::connect(m_CannelButton, SIGNAL(clicked(bool)), this, SLOT(onCannelClicked()));
// 初始化值
m_StateComboBox->setCurrentText("北京");
m_CityComboBox->setCurrentText("昌平");
this->setCustomerWindowTitle("日丽天气 V1.0 - by Douzhq");
}
WeatherCityChangeWindow::~WeatherCityChangeWindow()
{
}
void WeatherCityChangeWindow::onStateComboBoxIndexChanged(int index)
{
QString nProvinceName = m_StateComboBox->currentText();
QList<QString> cityNameList = chinaCityManager->getCitysName(nProvinceName);
m_CityComboBox->clear();
m_RegionComboBox->clear();
m_CityComboBox->addItems(cityNameList);
}
void WeatherCityChangeWindow::onCityComboBoxIndexChanged(int index)
{
QString nProvinceName = m_StateComboBox->currentText();
QString nCityName = m_CityComboBox->currentText();
QList<QString> regionNameList = chinaCityManager->getRegionsName(nProvinceName, nCityName);
m_RegionComboBox->clear();
m_RegionComboBox->addItems(regionNameList);
}
void WeatherCityChangeWindow::onOKClicked(void)
{
if (m_RegionComboBox->currentText().isEmpty())
{
g_WeatherInterface->setCurrentCityName(m_CityComboBox->currentText());
g_WeatherInterface->setAirQualityCityName(m_StateComboBox->currentText());
}
else
{
g_WeatherInterface->setCurrentCityName(m_RegionComboBox->currentText());
g_WeatherInterface->setAirQualityCityName(m_CityComboBox->currentText());
}
emit changeCity();
this->close();
}
void WeatherCityChangeWindow::onCannelClicked(void)
{
this->close();
}
每选择一次ComboBox中的内容,重新刷新下一级ComboBox的界面显示。最后为g_WeatherInterface全局天气接口设置位置信息并更新天气信息显示。