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

原创
2022-11-28
4439
12

能够切换中国国内的所有省、城市、县,使用的是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全局天气接口设置位置信息并更新天气信息显示。

不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:Qt 解析Json数据显示天气信息