登录
转载

使用聚合数据 API 实现 Windows 日历天气程序

发布于 2021-03-16 阅读 515
  • 聚合数据
转载

使用聚合数据 API(申请链接 https://www.juhe.cn/docs/api/id/73) 实现 Windows 日历天气程序,具体展现如下:

今日天气

1.jpg

未来七日天气

2.jpg

当年全部假期

3.jpg

最近的假期

4.jpg

calendar_weather.py

 
import json 
from urllib import request 
 
def get_supported_citys():
    #支持城市列表
    url = "http://v.juhe.cn/weather/citys?key=key"
    with request.urlopen(url) as f:
        allData = f.read().decode("utf-8")
        dataMap = json.loads(allData)
        if dataMap["error_code"] == 0:
            file_name = "supported_citys.txt"
            for root, dirs, files in os.walk("."):
                if file_name in files:
                    os.remove(os.path.join(root, file_name))
 
            ret = dataMap["result"]
            for data in ret:
                with open(file_name, "a") as f:
                    s = "%s %s %s %s" %(data["province"], data["city"], data["district"], data["id"])
                    f.write(s + "\r\n")
 
def get_weather_by_name_or_id(city_id):
    #根据城市名/id查询天气
    url = "http://v.juhe.cn/weather/index?cityname=" + city_id + "&dtype=json&format=2&key=key"
    with request.urlopen(url) as f:
        allData = f.read().decode("utf-8")
        dataMap = json.loads(allData)
        if dataMap["error_code"] == 0:
            ret = dataMap["result"]
            sk = ret["sk"]
            today = ret["today"]
            future = ret["future"]
            ret_lst = []
            ret_lst.append(sk["wind_strength"])
            ret_lst.append(sk["time"])
            ret_lst.append(today["date_y"])
            ret_lst.append(today["week"])
            ret_lst.append(today["city"])
            ret_lst.append(today["weather"])
            ret_lst.append(today["temperature"])
            ret_lst.append(today["wind"])
            for data in future:
                ret_lst.append(data["date"])
                ret_lst.append(data["week"])
                ret_lst.append(data["weather"])
                ret_lst.append(data["temperature"])
                ret_lst.append(data["wind"])
            return ret_lst
 
def get_today_calendar(date):
    #获取当天的详细信息
    url = "http://v.juhe.cn/calendar/day?date=" + date + "&key=key"
    with request.urlopen(url) as f:
        allData = f.read().decode("utf-8")
        dataMap = json.loads(allData)
        if dataMap["error_code"] == 0:
            ret = dataMap["result"]["data"];
            ret_lst = []
            ret_lst.append(ret["date"])
            ret_lst.append(ret["weekday"])
            ret_lst.append(ret["animalsYear"])
            ret_lst.append(ret["lunarYear"])
            ret_lst.append(ret["lunar"])
            ret_lst.append(ret["suit"])
            ret_lst.append(ret["avoid"])
            return ret_lst
 
def get_this_year_holiday(year):
    #获取当年的假期列表
    url = "http://v.juhe.cn/calendar/year?year=" + year + "&key=key"
    with request.urlopen(url) as f:
        allData = f.read().decode("utf-8")
        dataMap = json.loads(allData)
        if dataMap["error_code"] == 0:
            ret = json.loads(dataMap["result"]["data"]["holidaylist"])
            ret_lst = []
            for data in ret:
                ret_lst.append("%s %s" %(data["name"], data["startday"]))
            return ret_lst
 
def get_latest_holiday(year_month):
    #获取近期假期
    url = "http://v.juhe.cn/calendar/month?year-month=" + year_month + "&key=key"
    with request.urlopen(url) as f:
        allData = f.read().decode("utf-8")
        dataMap = json.loads(allData)
        if dataMap["error_code"] == 0:
            ret = dataMap["result"]["data"]
            ret = json.loads(ret["holiday"])
            ret_lst = []
            for data in ret:
                ret_lst.append(data["festival"])
                ret_lst.append(data["name"])
                ret_lst.append(data["desc"])
                ret_lst.append("%s" %(data["list#num#"]))
                for detail in data["list"]:
                    if detail["status"] == "1":
                        ret_lst.append("%s %s" %(detail["date"], "休"))
                    elif detail["status"] == "2":
                        ret_lst.append("%s %s" %(detail["date"], "班"))
            return ret_lst

mainwindow.cpp

#include "ui_mainwindow.h"
#include <QDir>
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include <QStringListModel>
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QFont font;
    font.setPixelSize(14);
    setFont(font);
    setWindowTitle(QStringLiteral("日历天气"));
 
    connect(ui->comboBox_province, SIGNAL(currentTextChanged(QString)), this, SLOT(provinceChanged(QString)));
    connect(ui->comboBox_city, SIGNAL(currentTextChanged(QString)), this, SLOT(cityChanged(QString)));
    connect(ui->listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(listwidgetChanged()));
 
    ui->comboBox_province->setSizeAdjustPolicy(QComboBox::AdjustToContents);
    ui->comboBox_city->setSizeAdjustPolicy(QComboBox::AdjustToContents);
    ui->comboBox_district->setSizeAdjustPolicy(QComboBox::AdjustToContents);
    ui->listWidget->setMaximumWidth(200);
 
    QStringList headersLst;
    headersLst << QStringLiteral("时间") << QStringLiteral("天气") << QStringLiteral("温度") << QStringLiteral("风力");
    ui->tableWidget->setColumnCount(headersLst.count());
    ui->tableWidget->setHorizontalHeaderLabels(headersLst);
 
    ui->tableWidget->setRowCount(7);
    ui->tableWidget->verticalHeader()->setVisible(false);
 
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
 
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
 
    ui->treeWidget->setHeaderHidden(true);
    ui->treeWidget->setColumnCount(1);
 
    readSupportedCitys();
    readSavedCitys();
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
 
    QFile file("saved_citys.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Text);
 
    QTextStream in(&file);
    in.setCodec("utf-8");
 
    int count = ui->listWidget->count();
    for (int i = 0; i < count; ++i)
    {
        QListWidgetItem *item = ui->listWidget->item(i);
        in << item->text() << " " << item->data(Qt::UserRole).toString() << endl;
    }
 
    file.close();
}
 
void MainWindow::readSavedCitys()
{
    QFile file("saved_citys.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("找不到saved_citys.txt文件"), QStringLiteral("确定"));
        return;
    }
 
    QTextStream in(&file);
    in.setCodec("utf-8");
 
    while (!in.atEnd())
    {
        QStringList strLst = in.readLine().split(" ");
        QListWidgetItem *item = new QListWidgetItem;
        item->setText(strLst[0]);
        item->setData(Qt::UserRole, strLst[1]);
        ui->listWidget->addItem(item);
    }
}
 
void MainWindow::getTodayCalendar(QString date)
{
    if (!initPython())
    {
        return;
    }
 
    PyObject *pFun = PyObject_GetAttrString(mPythonModule, "get_today_calendar");
    PyObject *args = Py_BuildValue("(s)", date.toStdString().c_str());
    PyObject *pRet = PyObject_CallObject(pFun, args);
 
    if (pRet == nullptr)
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("暂时获取不到数据"), QStringLiteral("确定"));
        return;
    }
 
    QString animalsYear = getPythonListByIndex(pRet, 2);
    QString lunarYear = getPythonListByIndex(pRet, 3);
    QString lunar = getPythonListByIndex(pRet, 4);
    QString suit = getPythonListByIndex(pRet, 5);
    QString avoid = getPythonListByIndex(pRet, 6);
 
    ui->label_lunar->setText(QStringLiteral("%1 %2 %3").arg(lunarYear).arg(animalsYear).arg(lunar));
    ui->label_suit->setText(suit.replace(".", " "));
    ui->label_avoid->setText(avoid.replace(".", " "));
 
    Py_Finalize();
}
 
void MainWindow::getThisYearHoliday(QString year)
{
    if (!initPython() || mIsAllHolidayGeted)
    {
        return;
    }
 
    PyObject *pFun = PyObject_GetAttrString(mPythonModule, "get_this_year_holiday");
    PyObject *args = Py_BuildValue("(s)", year.toStdString().c_str());
    PyObject *pRet = PyObject_CallObject(pFun, args);
 
    if (pRet == nullptr)
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("暂时获取不到数据"), QStringLiteral("确定"));
        return;
    }
 
    int count = PyList_Size(pRet);
    for (int i = 0; i < count; ++i)
    {
        QString str = getPythonListByIndex(pRet, i);
        QListWidgetItem *item = new QListWidgetItem;
        item->setText(str);
        ui->listWidget_2->addItem(item);
 
        if (!mIsAllHolidayGeted)
        {
            mIsAllHolidayGeted = true;
        }
    }
 
    Py_Finalize();
}
 
void MainWindow::getLatestHoliday(QString yearMonth)
{
    if (!initPython() || mIsLatestHolidayGeted)
    {
        return;
    }
 
    PyObject *pFun = PyObject_GetAttrString(mPythonModule, "get_latest_holiday");
    PyObject *args = Py_BuildValue("(s)", yearMonth.toStdString().c_str());
    PyObject *pRet = PyObject_CallObject(pFun, args);
 
    if (pRet == nullptr)
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("暂时获取不到数据"), QStringLiteral("确定"));
        return;
    }
 
    int count = PyList_Size(pRet);
    QString str;
    for (int i = 0; i < count;)
    {
        QString tmp = getPythonListByIndex(pRet, i);
 
        if (tmp.toInt())
        {
            QTreeWidgetItem *root = new QTreeWidgetItem(ui->treeWidget);
            QStringList strLst = str.split(" ");
            root->setText(0, QStringLiteral("%1:%2(%3)").arg(strLst[0]).arg(strLst[1]).arg(strLst[2]));
            ui->treeWidget->addTopLevelItem(root);
 
            for (int j = i + 1; j < i + 1 + tmp.toInt(); ++j)
            {
                QStringList lst;
                lst << getPythonListByIndex(pRet, j);
                QTreeWidgetItem *child = new QTreeWidgetItem(root, lst);
                root->addChild(child);
            }
 
            i = i + 1 + tmp.toInt();
            str = "";
        }
        else
        {
            if (str.isEmpty())
            {
                str = tmp;
            }
            else
            {
                str = str + " " + tmp;
            }
 
            i = i + 1;
        }
 
        if (!mIsLatestHolidayGeted)
        {
            mIsLatestHolidayGeted = true;
        }
    }
 
    Py_Finalize();
}
 
void MainWindow::readSupportedCitys()
{
    QFile file("supported_citys.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("找不到supported_citys.txt文件"), QStringLiteral("确定"));
        return;
    }
 
    QTextStream in(&file);
    in.setCodec("utf-8");
 
    QString oldProvince;
    QString oldCity;
    while (!in.atEnd())
    {
        QStringList strLst = in.readLine().split(" ");
 
        QString province = strLst[0];
        QString city = strLst[1];
        if (oldCity.isEmpty())
        {
            oldCity = city;
        }
        if (oldProvince.isEmpty())
        {
            oldProvince = province;
        }
 
        if (city != oldCity)
        {
            mCityDistrictMap.insert(oldCity, mDistrictIdMap);
            oldCity = city;
            mDistrictIdMap.clear();
        }
 
        if (province != oldProvince)
        {
            mProvinceCityMap.insert(oldProvince, mCityDistrictMap);
            oldProvince = province;
            mCityDistrictMap.clear();
        }
 
        mDistrictIdMap.insert(strLst[2], strLst[3]);
    }
 
    QStringList provinceLst;
    foreach (QString province, mProvinceCityMap.keys())
    {
        provinceLst << province;
    }
    QStringListModel *model = new QStringListModel;
    model->setStringList(provinceLst);
    ui->comboBox_province->setModel(model);
 
    file.close();
}
 
bool MainWindow::initPython()
{
    Py_Initialize();
    if (!Py_IsInitialized())
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("未能初始化Python库"), QStringLiteral("确定"));
        return false;
    }
 
    QString str = "sys.path.append('" + QDir::currentPath() + "')";
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(str.toStdString().c_str());
 
    mPythonModule = PyImport_ImportModule("calendar_weather");
    if (!mPythonModule)
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("找不到calendar_weather.py文件或文件存在语法错误"), QStringLiteral("确定"));
        return false;
    }
 
    return true;
}
 
void MainWindow::getWeatherById(QString id)
{
    if (!initPython())
    {
        return;
    }
 
    PyObject *pFun = PyObject_GetAttrString(mPythonModule, "get_weather_by_name_or_id");
    PyObject *args = Py_BuildValue("(s)", id.toStdString().c_str());
    PyObject *pRet = PyObject_CallObject(pFun, args);
 
    if (pRet == nullptr)
    {
        QMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("暂时获取不到数据"), QStringLiteral("确定"));
        return;
    }
 
    QString time = getPythonListByIndex(pRet, 1);
    QString date = getPythonListByIndex(pRet, 2);
    QString week = getPythonListByIndex(pRet, 3);
    QString city = getPythonListByIndex(pRet, 4);
    QString weather = getPythonListByIndex(pRet, 5);
    QString temperature = getPythonListByIndex(pRet, 6);
    QString wind = getPythonListByIndex(pRet, 7);
 
    ui->label_date->setText(QStringLiteral("%1 %2 %3")
                            .arg(date.replace(QStringLiteral("年"), "-").replace(QStringLiteral("月"), "-").replace(QStringLiteral("日"), ""))
                            .arg(week)
                            .arg(QStringLiteral("(更新时间 %1)").arg(time)));
    ui->label_city->setText(city);
    ui->label_weather->setText(weather);
    ui->label_temperature->setText(temperature);
    ui->label_wind->setText(wind);
 
    QString str = date.replace(QStringLiteral("年"), "-").replace(QStringLiteral("月"), "-").replace(QStringLiteral("日"), "");
    QStringList strLst = str.split("-");
 
    getTodayCalendar(QStringLiteral("%1-%2-%3").arg(strLst[0].toInt()).arg(strLst[1].toInt()).arg(strLst[2].toInt()));
    getThisYearHoliday(strLst[0]);
    getLatestHoliday(QStringLiteral("%1-%2").arg(strLst[0].toInt()).arg(strLst[1].toInt()));
 
    int row = 0;
    for (int index = 7; index < PyList_Size(pRet) - 5; index = index + 5)
    {
        QString futureDate = getPythonListByIndex(pRet, index + 1);
        futureDate = QStringLiteral("%1-%2-%3")
                .arg(futureDate.mid(0, 4))
                .arg(futureDate.mid(4, 2))
                .arg(futureDate.mid(6, 2));
        QString futureWeek = getPythonListByIndex(pRet, index + 2);
        QString futureWeather = getPythonListByIndex(pRet, index + 3);
        QString futureTemperature = getPythonListByIndex(pRet, index + 4);
        QString futureWind = getPythonListByIndex(pRet, index + 5);
 
        ui->tableWidget->setItem(row, 0, new QTableWidgetItem(QStringLiteral("%1 %2")
                                                              .arg(futureDate)
                                                              .arg(futureWeek)));
        ui->tableWidget->setItem(row, 1, new QTableWidgetItem(futureWeather));
        ui->tableWidget->setItem(row, 2, new QTableWidgetItem(futureTemperature));
        ui->tableWidget->setItem(row, 3, new QTableWidgetItem(futureWind));
 
        row = row + 1;
    }
 
    Py_Finalize();
}
 
QString MainWindow::getPythonListByIndex(PyObject *ret, int index)
{
    return QStringLiteral("%1").arg(PyUnicode_AsUTF8(PyList_GetItem(ret, index)));
}
 
void MainWindow::provinceChanged(const QString &province)
{
    QMap<QString, QMap<QString, QString>> map = mProvinceCityMap.value(province);
    QStringList cityLst;
    foreach (QString city, map.keys())
    {
        cityLst << city;
    }
 
    QStringListModel *model = new QStringListModel;
    model->setStringList(cityLst);
    ui->comboBox_city->setModel(model);
}
 
void MainWindow::cityChanged(const QString &city)
{
    ui->comboBox_district->clear();
    QMap<QString, QString> map = mProvinceCityMap.value(ui->comboBox_province->currentText()).value(city);
    foreach (QString district, map.keys())
    {
        ui->comboBox_district->addItem(district, map.value(district));
    }
}
 
void MainWindow::on_pushButton_clicked()
{
    if (ui->listWidget->count() == 0)
    {
        connect(ui->listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(listwidgetChanged()));
    }
 
    QString text = QStringLiteral("%1/%2/%3")
            .arg(ui->comboBox_province->currentText())
            .arg(ui->comboBox_city->currentText())
            .arg(ui->comboBox_district->currentText());
 
    int count = ui->listWidget->count();
    for (int i = 0; i < count; ++i)
    {
        QListWidgetItem *item = ui->listWidget->item(i);
        if (item->text() == text)
        {
            return;
        }
    }
 
    QListWidgetItem *item = new QListWidgetItem;
    item->setText(text);
    item->setData(Qt::UserRole, ui->comboBox_district->currentData());
    ui->listWidget->addItem(item);
}
 
void MainWindow::listwidgetChanged()
{
    QListWidgetItem *item =  ui->listWidget->currentItem();
    getWeatherById(item->data(Qt::UserRole).toString());
}
 
void MainWindow::on_pushButton_2_clicked()
{
    if (ui->listWidget->count() == 1)
    {
        disconnect(ui->listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(listwidgetChanged()));
    }
 
    QListWidgetItem *item = ui->listWidget->takeItem(ui->listWidget->currentRow());
    delete item;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mabing993/article/details/80574920

评论区

莲子
4粉丝

励志做一条安静的咸鱼,从此走上人生巅峰。

0

0

0

举报