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


文章目录

  • 一.准备工作
  • 二.预览
    • 1.启动
    • 2.日期切换
  • 三.设计流程
    • 1.整体流程
    • 2.UI设计(草图)
    • 3.UI设计(QT设计师)
  • 四.源代码
    • 1.History_Today_GUI.py(主程序)
    • 2.history_today.py(UI)
    • 3.history_event_get.py(获取数据)
  • 五.总结

本次使用PyQt5制作一款历史上的今天查看器,支持查看任一日期的历史事件,包括大事记、逝世事记、出生事记,简单又小巧,开始吧~
一.准备工作 请确保已经安装了Python3.X,安装以下第三方库。
  1. PyQt5
    用于QT代码的撰写
pip install PyQt5

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

二.预览 1.启动 启动以后软件自动加载当天的历史大事记,点击左侧的事件即可查看对应的事件详情。
GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)
文章图片

2.日期切换 在旋钮组件(SpinBox)中选择一个日期,就会转到所选日期的大事件(字体、字体颜色、背景色可单独设置)
GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)
文章图片

三.设计流程 1.整体流程 GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)
文章图片

2.UI设计(草图) 【GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)】GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)
文章图片

3.UI设计(QT设计师) GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)
文章图片

四.源代码 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 Falsedef 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,data1in 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=https://www.it610.com/article/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, QtWidgetsclass 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 etreeclass Event_Get:def __init__(self,month,day): self.month=month self.day=daydef title_clean(self,title): if "\xa0"in title: title=title.replace('\xa0','') if '·'in title : title=title.replace('·','') title_new=title return title_newdef 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 Nonedef 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 Falsedef 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=https://www.it610.com/article/_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_listdef 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,用于查看历史上某天发生的重大事件,程序打包好,放在了蓝奏云,欢迎各位使用、测试!思路、代码方面有什么不足欢迎各位大佬指正、批评!
GUI-PyQt5|python3GUI--历史上的今天 查看器 By:PyQt5(附源码)
文章图片

    推荐阅读