您现在的位置是:首页 >技术杂谈 >天气预报信息获取程序--GUI--可以使用网站首页技术杂谈

天气预报信息获取程序--GUI--可以使用

雨师@ 2024-07-25 00:01:01
简介天气预报信息获取程序--GUI--可以使用

 上次正对项目中需要填写项目日志,制作了一个命令行版本的下载天气信息的程序,满足日常需要,调整一下界面版本的程序

如果大家使用命令行的可以使用下面的版本(连接)

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_())

 

界面展示:

 

 程序目录结构:

 

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。