使用聚合数据 API(申请链接 [https://www.juhe.cn/docs/api/id/73](https://www.juhe.cn/docs/api/id/73)) 实现 Windows 日历天气程序,具体展现如下:
今日天气
未来七日天气
当年全部假期
最近的假期
calendar_weather.py
```# coding: utf-8
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 "mainwindow.h"
#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