admin 管理员组

文章数量: 887006

Qt 切换城市显示(切换省、县、城市位置)

能够切换中国国内的所有省、城市、县,使用的是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_OBJECTpublic: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文件

#include "UIChinaCity.h"
#include <QDomDocument>
#include <QDomElement>
#include <QFile>UIChinaCity::UIChinaCity(QObject *parent):QObject(parent)
{disposeCityList();
}UIChinaCity::~UIChinaCity()
{}void UIChinaCity::disposeCityList(void)
{QFile file("./data/LocList.xml");if (!file.open(QFile::ReadOnly))return;QDomDocument doc;if (!doc.setContent(&file)){file.close();return;}file.close();QDomElement rootElement = doc.documentElement();if (rootElement.tagName() != "Location")return;QDomElement chinaElement;QDomNodeList nodeLsit = rootElement.childNodes();for (int i=0; i<nodeLsit.count(); ++i){QDomElement element = nodeLsit.at(i).toElement();if (element.attribute("Name") == "中国"){chinaElement = element;break;}}if (chinaElement.isNull())return;QDomNodeList chinaNodeList = chinaElement.childNodes();for (int i=0; i<chinaNodeList.count(); ++i){// 解析省/直辖市QDomElement element = chinaNodeList.at(i).toElement();QString stateName = element.attribute("Name");QList<CityInfo> cityInfoList;cityInfoList.clear();// 解析城市QDomNodeList cityNodeList = element.childNodes();for (int j=0; j<cityNodeList.count(); ++j){QDomElement cityElement = cityNodeList.at(j).toElement();QString cityName = cityElement.attribute("Name");CityInfo cityInfo;cityInfo.cityName = cityName;QList<QString> regionNameList;regionNameList.clear();// 解析区QDomNodeList regionNodeList = cityElement.childNodes();for (int k=0; k<regionNodeList.count(); ++k){QDomElement regionElement = regionNodeList.at(k).toElement();QString regionName = regionElement.attribute("Name");regionNameList.push_back(regionName);}cityInfo.regionName = regionNameList;cityInfoList.push_back(cityInfo);}m_ChinaCityInfo.insert(stateName, cityInfoList);}
}QList<QString> UIChinaCity::getProvinceName(void)
{QList<QString> provinceNameList;provinceNameList.clear();for (auto itor = m_ChinaCityInfo.begin(); itor != m_ChinaCityInfo.end(); ++itor){provinceNameList.push_back(itor.key());}return provinceNameList;
}QList<QString> UIChinaCity::getCitysName(QString name)
{auto itor = m_ChinaCityInfo.find(name);QList<CityInfo> cityList = itor.value();QList<QString> cityNameList;cityNameList.clear();for (int i=0; i<cityList.count(); ++i){cityNameList.push_back(cityList.at(i).cityName);}return cityNameList;
}QList<QString> UIChinaCity::getRegionsName(QString stateName, QString cityName)
{auto itor = m_ChinaCityInfo.find(stateName);QList<CityInfo> cityList = itor.value();QList<QString> regionNameList;regionNameList.clear();for (int i=0; i<cityList.count(); ++i){if (cityList.at(i).cityName == cityName)return cityList.at(i).regionName;}return regionNameList;
}

界面调用部分代码如下:
WeatherCityChangeWindow.h文件

#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_OBJECTpublic: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);// 初始化下拉TagQHBoxLayout *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全局天气接口设置位置信息并更新天气信息显示。

本文标签: Qt 切换城市显示(切换省县城市位置)