上次正对项目中需要填写项目日志,制作了一个命令行版本的下载天气信息的程序,满足日常需要,调整一下界面版本的程序
如果大家使用命令行的可以使用下面的版本(连接)
https://ht666666.blog.csdn.net/article/details/131020276
一、项目遇到的问题:
------
一、遇到的坑一
程序遇到的问题,就是信号的处理的问题时候遇到问题一直解决不了,崩溃,找不到原因
1.排查多线程"QThread",使用多线程的时候要注意的是实现类的方式,是里面有个run方法,
2.实例化类的时候要启用start()方法,如下
--------------------------
遇到的坑二、
信号的调测,虽然对pyqt5不是很熟悉,所以调测了半天
信号的视线步骤:
1.注册信号在类里面第一个位置注册【类属性】,不能放在实例属性里面
《注册信号的位置与 信号触发emit在一个类里面--》产生信息的类里面》
(标记为第一类)
2.在另外一个类(标记为第二个类),获取信号以及创建槽函数(处理信息的函数)
3.回到第一个类,什么时机产生触发条件,
通过上面信号“”三部曲“”完成信号设定以及使用过程。
-------------------------------
其他代码在我的上一个命令行程序中保持基本一致。
上代码:
UI--代码【用PQT5 QT Designer设计的】
二、代码部分:
下面是代码:
界面代码:
gettq.py
-----
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'gettq.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(365, 297)
Form.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.groupBox = QtWidgets.QGroupBox(Form)
self.groupBox.setGeometry(QtCore.QRect(10, 30, 231, 221))
self.groupBox.setObjectName("groupBox")
self.pushButton_get = QtWidgets.QPushButton(self.groupBox)
self.pushButton_get.setGeometry(QtCore.QRect(30, 160, 181, 41))
self.pushButton_get.setObjectName("pushButton_get")
self.lineEdit_code = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit_code.setGeometry(QtCore.QRect(100, 28, 113, 20))
self.lineEdit_code.setObjectName("lineEdit_code")
self.lineEdit_end = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit_end.setGeometry(QtCore.QRect(100, 88, 113, 20))
self.lineEdit_end.setObjectName("lineEdit_end")
self.lineEdit_start = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit_start.setGeometry(QtCore.QRect(100, 58, 113, 20))
self.lineEdit_start.setObjectName("lineEdit_start")
self.lineEdit_endmm = QtWidgets.QLineEdit(self.groupBox)
self.lineEdit_endmm.setGeometry(QtCore.QRect(100, 118, 113, 20))
self.lineEdit_endmm.setObjectName("lineEdit_endmm")
self.label = QtWidgets.QLabel(self.groupBox)
self.label.setGeometry(QtCore.QRect(33, 30, 51, 20))
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.groupBox)
self.label_2.setGeometry(QtCore.QRect(30, 58, 54, 12))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(self.groupBox)
self.label_3.setGeometry(QtCore.QRect(30, 88, 54, 12))
self.label_3.setObjectName("label_3")
self.label_4 = QtWidgets.QLabel(self.groupBox)
self.label_4.setGeometry(QtCore.QRect(30, 118, 54, 12))
self.label_4.setObjectName("label_4")
self.groupBox_2 = QtWidgets.QGroupBox(Form)
self.groupBox_2.setGeometry(QtCore.QRect(240, 30, 120, 221))
self.groupBox_2.setObjectName("groupBox_2")
self.label_6 = QtWidgets.QLabel(self.groupBox_2)
self.label_6.setGeometry(QtCore.QRect(20, 30, 81, 16))
self.label_6.setObjectName("label_6")
self.label_7 = QtWidgets.QLabel(self.groupBox_2)
self.label_7.setGeometry(QtCore.QRect(20, 60, 81, 16))
self.label_7.setObjectName("label_7")
self.label_5 = QtWidgets.QLabel(Form)
self.label_5.setGeometry(QtCore.QRect(280, 260, 71, 20))
self.label_5.setObjectName("label_5")
self.label_show = QtWidgets.QLabel(Form)
self.label_show.setGeometry(QtCore.QRect(10, 270, 221, 20))
self.label_show.setText("")
self.label_show.setObjectName("label_show")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "获取天气信息[HT]"))
self.groupBox.setTitle(_translate("Form", "GETDATA"))
self.pushButton_get.setText(_translate("Form", "下载数据"))
self.label.setText(_translate("Form", "城市代码:"))
self.label_2.setText(_translate("Form", "开始年份:"))
self.label_3.setText(_translate("Form", "结束年份:"))
self.label_4.setText(_translate("Form", "结束月份:"))
self.groupBox_2.setTitle(_translate("Form", "常用城市代码"))
self.label_6.setText(_translate("Form", "西安:57036"))
self.label_7.setText(_translate("Form", "咸阳:57048"))
self.label_5.setText(_translate("Form", "作者:海涛"))
核心代码:
import json
import sys,re,datetime,csv
import requests
from PyQt5.QtCore import pyqtSignal, QThread
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMainWindow, QApplication,QWidget
from gettq import Ui_Form
# 在1的基础上,进行界面显示打印的信息
class Myclass(QWidget,Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
self.setGeometry(300, 300, 300, 365)
# 设置窗口固定大小
self.setFixedSize(self.height(), self.width())
# 点击按钮后调用函数
self.pushButton_get.clicked.connect(self.eventbtn)
# 优化措施,给读取框中赋值,避免后续不输入数字,默认赋初始值
self.lineEdit_code.setText('57048')
self.lineEdit_start.setText('2023')
self.lineEdit_end.setText('2023')
self.lineEdit_endmm.setText('5')
self.label_show.setText("准备就绪")
# 函数,处理函数
def eventbtn(self):
# 获取lineEdit 输入框输入的内容获取
lineEdit_code=int(self.lineEdit_code.text())
lineEdit_start=int(self.lineEdit_start.text())
lineEdit_end=int(self.lineEdit_end.text())
lineEdit_endmm=int(self.lineEdit_endmm.text())
# 实例化类,传入参数
self.weather = WeatherForecast(lineEdit_code, lineEdit_start, lineEdit_end, lineEdit_endmm)
# 实例话WeatherForecast类,为了使用里面的‘signal_info’信号
self.weather.signal.connect(self.labelshowfunc)
# 这里面是继承自QThread,启用类的说过start()
self.weather.start()
# print(lineEdit_code,lineEdit_start,lineEdit_end,lineEdit_endmm)
def labelshowfunc(self,eminfo):
print("主界面接受到的信息",eminfo)
# 在GUI界面上label_show显示日志信息
self.label_show.setText(eminfo)
# 后台下载信息显示在这个标签里
# self.label_show.setText()
# class WeatherForecast(object):
class WeatherForecast(QThread):
# 定义一个信号,把信息发送到另外一个类的 lable中显示内容,用来通知显示信息
signal=pyqtSignal(str)
def __init__(self,city_code,start_year,end_year,end_month):
super().__init__()
self.city_code=city_code
self.start_year=start_year
self.end_year=end_year
self.end_month=end_month
# self.url = 'https://tianqi.2345.com/Pc/GetHistory?areaInfo%5BareaId%5D=59493&areaInfo%5BareaType%5D=2&date%5Byear%5D={0}&date%5Bmonth%5D={1}'
# #西安地址链接 57036--->BareaId%5D=59493
# self.url = 'https://tianqi.2345.com/Pc/GetHistory?areaInfo%5BareaId%5D=57036&areaInfo%5BareaType%5D=2&date%5Byear%5D={0}&date%5Bmonth%5D={1}'
# 咸阳地址链接57048--->%5BareaId%5D=59493
# self.url = 'https://tianqi.2345.com/Pc/GetHistory?areaInfo%5BareaId%5D=57048&areaInfo%5BareaType%5D=2&date%5Byear%5D={0}&date%5Bmonth%5D={1}'
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.24',
'accept-encoding': 'gzip, deflate, br'
}
self.data_list = []
def get_content(self, url):
res = requests.get(url=url, headers=self.headers)
content = res.json()
# print(content['data'])
return content['data']
def parse_data(self, content):
result = re.compile(r'<td>(?P<date>.*?)</td>.*?<td style="color:#ff5040;">(?P<max>.*?)</td>'
r'.*?<td style="color:#3097fd;" >(?P<min>.*?)</td>.*?<td>(?P<weather>.*?)</td>'
r'.*?<td>(?P<cloud>.*?)</td>.*?<td><span class="history-aqi wea-aqi.*?>(?P<sky>.*?)</span></td>',
re.S)
find_result = result.finditer(content)
for it in find_result:
data_dict = it.groupdict()
# print(data_dict)
self.data_list.append(data_dict)
return self.data_list
def write_csv(self, data_list):
curent_date=datetime.datetime.now().strftime("%Y%m%d")
save_name=str(self.city_code)+curent_date+'.csv'
with open(save_name, 'w',newline='') as f:
writer = csv.writer(f)
writer.writerow(['日期', '最高温度', '最低温度', '天气', '风力风向', '空气质量'])
for i in data_list:
writer.writerow(i.values())
# print(i.values())
# 爬取数据的事项,只能获取整年,如果到月份的话 if year==2024 & month>6:
# continue 通过他跳过指定的月份,获取数据
def run(self):
for year in range(self.start_year, self.end_year+1, 1):
for month in range(1, 13, 1):
if year>self.end_year:
continue
elif year==self.end_year:
if month>self.end_month:
continue
url = f'https://tianqi.2345.com/Pc/GetHistory?areaInfo%5BareaId%5D={self.city_code}&areaInfo%5BareaType%5D=2&date%5Byear%5D={year}&date%5Bmonth%5D={month}'
print('正在获取第{0}年{1}月的天气!'.format(year, month))
content = self.get_content(url)
# print(content,"json---->")
data = self.parse_data(content)
# self.signal.emit("正在写入数据中,请稍等...")
self.signal.emit("数据下载中...")
self.write_csv(data)
self.signal.emit('全部下载完毕')
print('全部获取完毕,请在程序目录获取下载xxxx.csv!')
if __name__ == '__main__':
app=QApplication(sys.argv)
win=Myclass()
win.setWindowIcon(QIcon("lob.ico"))
win.show()
sys.exit(app.exec_())
界面展示:
程序目录结构: