python3GUI--历史上的今天 查看器 By:PyQt5(附源码)


本次使用PyQt5制作一款历史上的今天查看器,支持查看任一日期的历史事件,包括大事记、逝世事记、出生事记,简单又小巧,开始吧~

一.准备工作

请确保已经安装了Python3.X,安装以下第三方库。

  1. PyQt5
    用于QT代码的撰写
pip install PyQt5

2.PyQt5-tools
使用其中的QT设计师,进行QT界面设计

pip install PyQt5-tools

二.预览

1.启动

启动以后软件自动加载当天的历史大事记,点击左侧的事件即可查看对应的事件详情。
在这里插入图片描述

2.日期切换

在旋钮组件(SpinBox)中选择一个日期,就会转到所选日期的大事件(字体、字体颜色、背景色可单独设置)
在这里插入图片描述

三.设计流程

1.整体流程

在这里插入图片描述

2.UI设计(草图)

在这里插入图片描述

3.UI设计(QT设计师)

在这里插入图片描述

四.源代码

1.History_Today_GUI.py(主程序)

import socket
import sys
import requests
import webbrowser
from PyQt5.uic import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from history_today import Ui_MainWindow
from history_event_get import Event_Get

"""
希望对按照时间升序排列事件   **已实现**
单击label改变颜色
异常处理优化  如:启动等待时间长   **判断网络连接状态**
"""

class Big_Eventts(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui=Ui_MainWindow()
        self.ui.setupUi(self)
        current_date = QDate.currentDate()
        if self.check_network():
            self.load_events(current_date)#首次启动初始化
        else:
            QMessageBox.warning(self, "警告", "请先连接到互联网,再使用本软件!")
            self.destroy(self)
        self.ui.dateTimeEdit.setDate(current_date)#初始化时间
        self.ui.dateTimeEdit.dateChanged.connect(self.load_events)
        self.ui.tableWidget_1.cellClicked.connect(self.show_event_detail)
        self.ui.tableWidget_2.cellClicked.connect(self.show_event_detail)
        self.ui.tableWidget_3.cellClicked.connect(self.show_event_detail)
        self.ui.action_about_software.triggered.connect(lambda :QMessageBox.information(self,"关于软件","以铜为镜,可以正衣冠。\n以史为镜,可以知兴替。\n以人为镜,可以明得失。\n\t\t——李世民  《旧唐书·魏徵传》"))
        self.ui.action_about_author.triggered.connect(lambda :QMessageBox.information(self,"关于作者","作者:懷淰メ\nBy:PyQT5"))
        self.ui.action_setFont.triggered.connect(self.set_font)
        self.ui.action_quit.triggered.connect(lambda :self.close())
        self.ui.action_home_page.triggered.connect(lambda :webbrowser.open('https://blog.csdn.net/a1397852386'))
        self.ui.action_set_fg_color.triggered.connect(self.set_fg_color)
        self.ui.action_set_bg_color.triggered.connect(self.set_bg_color)
        self.ui.pushButton.clicked.connect(lambda :self.load_events(current_date))
        self.ui.tableWidget_2.verticalHeader().setVisible(True)#这里出现了bug,在QT设计师设计保存了,还是会改变

    def check_network(self):
        #检查设备是否连接互联网
        try:
            r=requests.get('http://www.baidu.com',timeout=3)
            if r.status_code==200:
                return True
            else:
                return False
        except:
            return False

    def load_events(self,date):
        """
        加载三部分的事件
        :return:
        """
        try:
            if date==QDate.currentDate():
                self.ui.pushButton.setEnabled(False)
            else:
                self.ui.pushButton.setEnabled(True)
            self.ui.tabWidget.setCurrentIndex(0)
            self.ui.textEdit.clear()
            month,day=date.toString('MM-dd').split('-')
            self.spider=Event_Get(month,day)
            big_events=self.spider.get_evnets(1)
            self.big_events=big_events
            self.ui.tableWidget_1.setRowCount(len(big_events))
            for index,data1  in enumerate(big_events):
                new_item1=QTableWidgetItem(data1['event'])
                self.ui.tableWidget_1.setItem(index, 0, new_item1)
            cs_events=self.spider.get_evnets(2)
            self.cs_events=cs_events
            self.ui.tableWidget_2.setRowCount(len(cs_events))
            for index, data2 in enumerate(cs_events):
                new_item2 = QTableWidgetItem(data2['event'])
                self.ui.tableWidget_2.setItem(index, 0, new_item2)
            ss_events=self.spider.get_evnets(3)
            self.ss_events=ss_events
            self.ui.tableWidget_3.setRowCount(len(ss_events))
            for index, data3 in enumerate(ss_events):
                new_item3 = QTableWidgetItem(data3['event'])
                self.ui.tableWidget_3.setItem(index, 0, new_item3)
        except:
            QMessageBox.critical(self,"错误",'数据加载错误,请检查网络!')

    def show_event_detail(self,row,_)->None:
        """
        显示所选事件详情
        :param row: 行
        :param _: 列,在此处无用
        :return: None
        """
        tablewidget_index=int(self.sender().objectName().split('_')[-1])
        if tablewidget_index==1:
            data=self.big_events[row]
        elif tablewidget_index==2:
            data=self.cs_events[row]
        elif tablewidget_index==3:
            data=self.ss_events[row]
        event_link=data['link']
        detail=self.spider.get_event_detail(event_link)
        self.ui.textEdit.setPlainText(detail)

    def set_font(self):
        """
        设置字体、大小、特殊
        :return:
        """
        font,ok=QFontDialog.getFont()
        if ok :
            self.ui.textEdit.setFont(font)

    def set_fg_color(self):
        """
        设置字体颜色
        :return:
        """
        color=QColorDialog.getColor()
        self.ui.textEdit.setTextColor(color)

    def set_bg_color(self):
        """
        使用QSS 设置textedit背景色
        :return:
        """
        color=QColorDialog.getColor()
        self.ui.textEdit.setStyleSheet("QTextEdit{background-color:%s;}"%color.name())

    def closeEvent(self,event):
        ret=QMessageBox.question(self,'退出','确定要退出?',QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
        if ret==QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()


if __name__ == '__main__':
    app=QApplication(sys.argv)
    ui=Big_Eventts()
    ui.show()
    sys.exit(app.exec_())

2.history_today.py(UI)

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'history_today.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(805, 624)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setContentsMargins(-1, 10, -1, -1)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.label_title = QtWidgets.QLabel(self.centralwidget)
        self.label_title.setStyleSheet("QLabel{\n"
"color:rgb(170, 85, 0);\n"
"font-size:30px;\n"
"font-family:\"Times New Roman\"\n"
"}")
        self.label_title.setObjectName("label_title")
        self.horizontalLayout_2.addWidget(self.label_title)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem2)
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.dateTimeEdit = QtWidgets.QDateTimeEdit(self.centralwidget)
        self.dateTimeEdit.setCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
        self.dateTimeEdit.setReadOnly(False)
        self.dateTimeEdit.setCurrentSection(QtWidgets.QDateTimeEdit.MonthSection)
        self.dateTimeEdit.setCalendarPopup(True)
        self.dateTimeEdit.setTimeSpec(QtCore.Qt.LocalTime)
        self.dateTimeEdit.setObjectName("dateTimeEdit")
        self.horizontalLayout.addWidget(self.dateTimeEdit)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem3)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setMinimumSize(QtCore.QSize(30, 0))
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem4)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setTabPosition(QtWidgets.QTabWidget.North)
        self.tabWidget.setTabShape(QtWidgets.QTabWidget.Triangular)
        self.tabWidget.setTabBarAutoHide(False)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.tab)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.tableWidget_1 = QtWidgets.QTableWidget(self.tab)
        self.tableWidget_1.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_1.setAlternatingRowColors(True)
        self.tableWidget_1.setWordWrap(False)
        self.tableWidget_1.setObjectName("tableWidget_1")
        self.tableWidget_1.setColumnCount(1)
        self.tableWidget_1.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_1.setHorizontalHeaderItem(0, item)
        self.tableWidget_1.horizontalHeader().setVisible(False)
        self.tableWidget_1.horizontalHeader().setCascadingSectionResizes(False)
        self.tableWidget_1.horizontalHeader().setStretchLastSection(True)
        self.verticalLayout_2.addWidget(self.tableWidget_1)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.tab_2)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.tableWidget_2 = QtWidgets.QTableWidget(self.tab_2)
        self.tableWidget_2.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_2.setAlternatingRowColors(True)
        self.tableWidget_2.setWordWrap(False)
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(1)
        self.tableWidget_2.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_2.setHorizontalHeaderItem(0, item)
        self.tableWidget_2.horizontalHeader().setVisible(False)
        self.tableWidget_2.horizontalHeader().setStretchLastSection(True)
        self.tableWidget_2.verticalHeader().setVisible(False)
        self.horizontalLayout_6.addWidget(self.tableWidget_2)
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.tab_3)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.tableWidget_3 = QtWidgets.QTableWidget(self.tab_3)
        self.tableWidget_3.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget_3.setAlternatingRowColors(True)
        self.tableWidget_3.setWordWrap(False)
        self.tableWidget_3.setObjectName("tableWidget_3")
        self.tableWidget_3.setColumnCount(1)
        self.tableWidget_3.setRowCount(0)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget_3.setHorizontalHeaderItem(0, item)
        self.tableWidget_3.horizontalHeader().setVisible(False)
        self.tableWidget_3.horizontalHeader().setStretchLastSection(True)
        self.horizontalLayout_4.addWidget(self.tableWidget_3)
        self.tabWidget.addTab(self.tab_3, "")
        self.horizontalLayout_5.addWidget(self.tabWidget)
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setObjectName("groupBox")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.textEdit = QtWidgets.QTextEdit(self.groupBox)
        self.textEdit.setStyleSheet("")
        self.textEdit.setObjectName("textEdit")
        self.horizontalLayout_3.addWidget(self.textEdit)
        self.horizontalLayout_5.addWidget(self.groupBox)
        self.verticalLayout.addLayout(self.horizontalLayout_5)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 805, 26))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menubar)
        self.menu_2.setObjectName("menu_2")
        self.menu_3 = QtWidgets.QMenu(self.menubar)
        self.menu_3.setObjectName("menu_3")
        MainWindow.setMenuBar(self.menubar)
        self.action_about_software = QtWidgets.QAction(MainWindow)
        self.action_about_software.setObjectName("action_about_software")
        self.action_about_author = QtWidgets.QAction(MainWindow)
        self.action_about_author.setObjectName("action_about_author")
        self.action_quit = QtWidgets.QAction(MainWindow)
        self.action_quit.setObjectName("action_quit")
        self.action_setFont = QtWidgets.QAction(MainWindow)
        self.action_setFont.setObjectName("action_setFont")
        self.action_home_page = QtWidgets.QAction(MainWindow)
        self.action_home_page.setObjectName("action_home_page")
        self.action_set_bg_color = QtWidgets.QAction(MainWindow)
        self.action_set_bg_color.setObjectName("action_set_bg_color")
        self.action_set_fg_color = QtWidgets.QAction(MainWindow)
        self.action_set_fg_color.setObjectName("action_set_fg_color")
        self.menu.addAction(self.action_home_page)
        self.menu.addSeparator()
        self.menu.addAction(self.action_quit)
        self.menu_2.addAction(self.action_about_software)
        self.menu_2.addAction(self.action_about_author)
        self.menu_3.addAction(self.action_setFont)
        self.menu_3.addAction(self.action_set_fg_color)
        self.menu_3.addAction(self.action_set_bg_color)
        self.menubar.addAction(self.menu.menuAction())
        self.menubar.addAction(self.menu_3.menuAction())
        self.menubar.addAction(self.menu_2.menuAction())

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "历史上的今天"))
        self.label_title.setText(_translate("MainWindow", "历史上的今天"))
        self.label.setText(_translate("MainWindow", "选择一个日期:"))
        self.dateTimeEdit.setDisplayFormat(_translate("MainWindow", "MM月dd日"))
        self.pushButton.setText(_translate("MainWindow", "回今天"))
        item = self.tableWidget_1.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "事件"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "大事记"))
        item = self.tableWidget_2.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "事件"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "出生"))
        item = self.tableWidget_3.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "事件"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "逝世"))
        self.groupBox.setTitle(_translate("MainWindow", "事件详情"))
        self.menu.setTitle(_translate("MainWindow", "开始"))
        self.menu_2.setTitle(_translate("MainWindow", "关于"))
        self.menu_3.setTitle(_translate("MainWindow", "设置"))
        self.action_about_software.setText(_translate("MainWindow", "关于软件"))
        self.action_about_author.setText(_translate("MainWindow", "关于作者"))
        self.action_quit.setText(_translate("MainWindow", "退出"))
        self.action_setFont.setText(_translate("MainWindow", "设置字体"))
        self.action_home_page.setText(_translate("MainWindow", "访问作者主页"))
        self.action_set_bg_color.setText(_translate("MainWindow", "设置背景颜色"))
        self.action_set_fg_color.setText(_translate("MainWindow", "设置字体颜色"))

3.history_event_get.py(获取数据)

import requests
import json
import re
from urllib.parse import urljoin
from lxml import etree

class Event_Get:

    def __init__(self,month,day):
        self.month=month
        self.day=day

    def title_clean(self,title):
        if "\xa0"in title:
            title=title.replace('\xa0','')
        if '·'in title :
            title=title.replace('·','')
        title_new=title
        return title_new

    def get_html(self,url):
        """
        获取文本代码
        :param url:
        :return:
        """
        headers={
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4662.6 Safari/537.36',
            'Host': 'jintian.160.com',
            'Referer': url
        }
        r=requests.get(url,headers=headers)
        if r.status_code==200:
            r.encoding='utf-8'
            html=r.text
            return html
        else:
            return None

    def get_sum_page_num(self,url):
        """
        获取数据总页数
        :param url:
        :return:
        """
        html = self.get_html(url)
        if html:
            _json=json.loads(html)
            recordCount=_json.get('recordCount')
            if recordCount<=14:
                page_num=1
            else:
                i,r=divmod(recordCount,14)
                if r==0:
                    page_num=i
                else:
                    page_num=1+1
            return page_num
        else:
            return False

    def get_evnets(self,type):
        """
        获取事件
        :param type:
        :return:
        """
        if type == 1:
            # 大事记
            url = f'http://jintian.160.com/ashx/GreatThing.ashx?act=getgreatthinglist&page=1&m={self.month}&d={self.day}&c=dsj'
        elif type == 2:
            # 出生
            url = f'http://jintian.160.com/ashx/GreatThing.ashx?act=getgreatthinglist&page=1&m={self.month}&d={self.day}&c=cs'
        elif type == 3:
            # 逝世
            url = f'http://jintian.160.com/ashx/GreatThing.ashx?act=getgreatthinglist&page=1&m={self.month}&d={self.day}&c=ss'
        sum_page_num=self.get_sum_page_num(url)
        event_list = []
        for i in range(1,sum_page_num+1):
            new_url=url.replace('&page=1',f'&page={i}')
            html = self.get_html(new_url)
            if html:
                _json=json.loads(html)
                data=_json.get('data')
                res=etree.HTML(data)
                selector=res.xpath('//body/li')
                for data in selector:
                    item={}
                    title1=data.xpath('./a/@title')
                    if title1:
                        event=self.title_clean(''.join(title1))
                        link = data.xpath('./a/@href')
                        item['link'] = urljoin(url, ''.join(link))
                    else:
                        event=data.xpath('./text()')
                        item['link'] = None
                    item['event'] = self.title_clean(''.join(event))
                    event_list.append(item)
        try:
            new_list=sorted(event_list,key=lambda a:int(a['event'].split('年')[0]),reverse=False)
            return new_list
        except:
            return event_list

    def get_event_detail(self,url):
        # url='http://jintian.160.com/dsj/10/6/p2/19467.html#wz'
        if url==None:
            return "没有详细介绍哦~"
        html=self.get_html(url)
        res=etree.HTML(html)
        content=res.xpath('//div[@class="news_box2"]/div[@id="gContent"]/p/text()')
        if len(content)!=0:
            return '\n'.join(content)
        else:
            return "没有详细介绍哦~"

五.总结

使用PyQT5制作了一款GUI,用于查看历史上某天发生的重大事件,程序打包好,放在了蓝奏云,欢迎各位使用、测试!思路、代码方面有什么不足欢迎各位大佬指正、批评!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值