共计 13502 个字符,预计需要花费 34 分钟才能阅读完成。
应用聚合数据 API(申请链接 https://www.juhe.cn/docs/api/id/73) 实现 Windows 日历天气程序,具体展示如下:
今日天气
将来七日天气
当年全副假期
最近的假期
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/mabing9…
正文完