Python爬虫技术及PyQt5界面编程实现12306火车票查询

界面设计

界面设计使用了Qt 设计师(使用方法请自行探索)实现拖拽生成:
在这里插入图片描述
设计保存后会生成一个后缀位ui的文件,将这个文件放进项目中,此时我们还不能直接运行这个文件,也看不到界面,此时在PyCharm中做如下配置:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
程序:python.exe所在的目录

实参:-m PyQt5.uic.pyuic$FileName$ -o $FileNameWithoutExtension$.py

工作目录:$FileDir$

添加好之后返回项目界面,右键刚才的ui后缀文件

在这里插入图片描述
选择External Tools—>PyUIC
执行后同级目录下会生成一个同名的py文件在这里插入图片描述
此时的py文件运行是不能出现界面的,在刚才生成的py文件中添加如下代码:

# 显示主窗体
def show_MainWindow():
    app = QtWidgets.QApplication(sys.argv)  # 实例化QApplication,作为GUI主程序入口
    MainWindow = QtWidgets.QMainWindow()  # 创建QMainWindow
    ui = Ui_MainWindow()  # 实例UI类
    ui.setupUi(MainWindow)  # 设置窗体UI
    MainWindow.show()  # 显示窗体
    sys.exit(app.exec_())  # 当窗口创建完成后需要结束主循环
if __name__ == '__main__':
	show_MainWindow()  # 调用显示窗体的方法

此时则可以实现运行出界面。(设计时的图片等路径可能需要更改才能正确显示

技术实现

1、12306网页车票查询分析

此处需要具备爬虫知识
经过分析得知:

url=‘https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9050’

这个链接就是获取车站的链接(输入车站名时怎么进行查询的?分析发现是根据 中文名对应的英文缩写,而这个链接就是获取这种对应关系的)

获取车站信息代码:

# -*- coding: utf-8 -*-
"""
-------------------------------------------------
  File Name:    get_stations.py
  Author:        lenovo
  Date:         2021/12/20
  Create by:     PyCharm
  Description :  获取车站信息---中文和对应英文缩写
-------------------------------------------------
"""
import os
import re

import requests

"""
1、”utf-8“ 是以字节为编码单元,它的字节顺序在所有系统中都是一样的,
    没有字节序问题,因此它不需要BOM,所以当用"utf-8"编码方式读取带有BOM的文件时,
    它会把BOM当做是文件内容来处理, 也就会发生类似上边的错误.
2、“utf-8-sig"中sig全拼为 signature 也就是"带有签名的utf-8”, 
    因此"utf-8-sig"读取带有BOM的"utf-8文件时"会把BOM单独处理,
    与文本内容隔离开,也是我们期望的结果.
"""


def getStation():
    # 发送请求获取所有车站名称,通过输入的站名称转化查询地址的参数
    url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9050'
    response = requests.get(url, verify=True)  # 请求并进行验证
    stations = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)  # 获取需要的车站名称
    stations = dict(stations)  # 转换为dic
    stations = str(stations)  # 转换为字符串类型否则无法写入文件
    write(stations)  # 调用写入方法


def write(stations):
    if not os.path.exists('station/'):  # 如果文件目录不存在则创建
        os.makedirs('station/')

    with open('station/stations.text', 'w', encoding='utf_8_sig') as f:  # w文本写入
        f.write(stations)
        f.close()


def read():
    file = open('station/stations.text', 'r', encoding='utf_8_sig')  # 以写模式打开文件
    data = file.readline()  # 读取文件
    file.close()
    return data


def isStations():
    isExist = os.path.exists('station/stations.text')  # 判断车站文件是否存在
    return isExist

获取查询结果

# -*- coding: utf-8 -*-
"""
-------------------------------------------------
  File Name:    query_data.py
  Author:        lenovo
  Date:         2021/12/20
  Create by:     PyCharm
  Description :  查询车辆信息
-------------------------------------------------
"""
from get_stations import *

'''
5-7 目的地 3  车次 6  出发地 8  出发时间 9  到达时间 10 历时 26 无坐 29 硬座
24 软座 28 硬卧 33 动卧 23 软卧 21 高级软卧 30 二等座 31 一等座 32 商务座特等座
'''
data = []  # 用于保存整理好的车次信息
type_data = []  # 保存车次分类后最后的数据


def query(date, from_station, to_station):
    """
    根据传入的日期,起始车站,目的车站返回查询结果
    :param date: 出发日期
    :param from_station: 起始车站
    :param to_station: 目的车站
    :return: 查询数据
    """
    data.clear()  # 清空数据
    type_data.clear()  # 清空车次分类保存的数据
    headers = {
        'Cookie': "_uab_collina=163999108472034091142832; JSESSIONID=C5C4C5E7526DC0B7BFC6A5717D1F8380; BIGipServerotn=368050698.24610.0000; BIGipServerpool_passport=115606026.50215.0000; RAIL_EXPIRATION=1640270981777; RAIL_DEVICEID=lbec11dld1VeM-sTt-5XFnXTNwhNgpCur_gC8sJjGNMKKBV3uSi0ISD97wfIwWm3kwTRoZUeiv4uB7BtHpBl_bA_6px32mcN8aNpC6MMoP9VmpMINrZxxaQM_KNWIV7rZ7mND7kKrQxv5MTYmOMh6-I-KYFHkTvj; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; route=495c805987d0f5c8c84b14f60212447d; _jc_save_fromDate=2021-12-20; _jc_save_toDate=2021-12-20; _jc_save_wfdc_flag=dc; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_toStation=%u4E0A%u6D77%2CSHH",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62"
    }
    # 查询请求地址
    url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(
        date, from_station, to_station)
    # 发送查询请求
    response = requests.get(url=url, headers=headers)
    response.encoding = response.apparent_encoding
    # # 将json数据转换为字典类型,通过键值对取数据
    if response.status_code != 200:  # 直接返回空
        return data

    result = response.json()['data']['result']
    # for i in result:
    #     print(i)

    if isStations():
        stations = eval(read())  # 读取所有车站并转换为dic类型
        if len(result) != 0:  # 判断返回数据是否为空
            for i in result:
                # # 分割数据并添加到列表中
                tmp_list = i.split('|')
                # 因为查询结果中出发站和到达站为站名的缩写字母,所以需要在车站库中找到对应的车站名称
                from_station = list(stations.keys())[list(stations.values()).index(tmp_list[6])]
                to_station = list(stations.keys())[list(stations.values()).index(tmp_list[7])]
                # 创建座位数组,由于返回的座位数据中含有空既“”,所以将空改成--这样好识别
                seat = [tmp_list[3], from_station, to_station, tmp_list[8], tmp_list[9], tmp_list[10], tmp_list[32],
                        tmp_list[31], tmp_list[30], tmp_list[21], tmp_list[23], tmp_list[33], tmp_list[28],
                        tmp_list[24], tmp_list[29], tmp_list[26]]
                newSeat = []
                # 循环将座位信息中的空即“”,改成--这样好识别
                for s in seat:
                    if s == "":
                        s = "--"
                    else:
                        s = s
                    newSeat.append(s)  # 保存新的座位信息
                data.append(newSeat)
        return data  # 返回整理好的车次信息


# 获取高铁信息的方法
def g_vehicle():
    if len(data) != 0:
        for g in data:  # 循环所有火车数据
            i = g[0].startswith('G')  # 判断车次首字母是不是高铁
            if i:  # 如果是将该条信息添加到高铁数据中
                type_data.append(g)


# 移除高铁信息的方法
def r_g_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for g in data:
            i = g[0].startswith('G')
            if i:  # 移除高铁信息
                type_data.remove(g)


# 获取动车信息的方法
def d_vehicle():
    if len(data) != 0:
        for d in data:  # 循环所有火车数据
            i = d[0].startswith('D')  # 判断车次首字母是不是动车
            if i == True:  # 如果是将该条信息添加到动车数据中
                type_data.append(d)


# 移除动车信息的方法
def r_d_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for d in data:
            i = d[0].startswith('D')
            if i == True:  # 移除动车信息
                type_data.remove(d)


# 获取直达车信息的方法
def z_vehicle():
    if len(data) != 0:
        for z in data:  # 循环所有火车数据
            i = z[0].startswith('Z')  # 判断车次首字母是不是直达
            if i == True:  # 如果是将该条信息添加到直达数据中
                type_data.append(z)


# 移除直达车信息的方法
def r_z_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for z in data:
            i = z[0].startswith('Z')
            if i == True:  # 移除直达车信息
                type_data.remove(z)


# 获取特快车信息的方法
def t_vehicle():
    if len(data) != 0:
        for t in data:  # 循环所有火车数据
            i = t[0].startswith('T')  # 判断车次首字母是不是特快
            if i == True:  # 如果是将该条信息添加到特快车数据中
                type_data.append(t)


# 移除特快车信息的方法
def r_t_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for t in data:
            i = t[0].startswith('T')
            if i == True:  # 移除特快车信息
                type_data.remove(t)


# 获取快速车数据的方法
def k_vehicle():
    if len(data) != 0:
        for k in data:  # 循环所有火车数据
            i = k[0].startswith('K')  # 判断车次首字母是不是快车
            if i == True:  # 如果是将该条信息添加到快车数据中
                type_data.append(k)


# 移除快速车数据的方法
def r_k_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for k in data:
            i = k[0].startswith('K')
            if i == True:  # 移除快车信息
                type_data.remove(k)

在主界面综合爬虫实现查询并展示结果

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

# Form implementation generated from reading ui file 'main.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# 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.
import datetime
import sys
import time

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from query_data import *


# UI类
class Ui_MainWindow(object):
    # 设置UI方法
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")  # 设置窗体对象名称
        MainWindow.resize(960, 786)  # 设置窗体大小
        MainWindow.setMinimumSize(QtCore.QSize(960, 786))  # 主窗体最小值
        MainWindow.setMaximumSize(QtCore.QSize(960, 786))  # 主窗体最大值
        # MainWindow.setStyleSheet("*{border:1px solid blue}")
        self.centralwidget = QtWidgets.QWidget(MainWindow)  # 主窗体的widget控件
        self.centralwidget.setObjectName("centralwidget")  # 设置对象名称

        # --------------通过label控件setStyleSheet显示顶部图片-------------
        self.label_title_img = QtWidgets.QLabel(self.centralwidget)
        self.label_title_img.setGeometry(QtCore.QRect(0, 0, 960, 141))
        font = QtGui.QFont()
        font.setPointSize(20)
        self.label_title_img.setFont(font)
        self.label_title_img.setStyleSheet("background-image: url(img/bg1.png);")
        self.label_title_img.setText("")
        self.label_title_img.setObjectName("label_title_img")

        # ----------------选择车次类型的widget----------------------------
        self.widget_checkBox = QtWidgets.QWidget(self.centralwidget)
        self.widget_checkBox.setGeometry(QtCore.QRect(0, 220, 961, 35))
        self.widget_checkBox.setAutoFillBackground(False)
        self.widget_checkBox.setStyleSheet("background-image: url(img/bg3.png);")
        self.widget_checkBox.setObjectName("widget_checkBox")
        # 选择特快
        self.checkBox_T = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_T.setGeometry(QtCore.QRect(580, 5, 80, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.checkBox_T.setFont(font)
        self.checkBox_T.setObjectName("checkBox_T")
        # 选择快速
        self.checkBox_K = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_K.setGeometry(QtCore.QRect(720, 5, 80, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.checkBox_K.setFont(font)
        self.checkBox_K.setObjectName("checkBox_K")
        # 选择直达
        self.checkBox_Z = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_Z.setGeometry(QtCore.QRect(440, 5, 80, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.checkBox_Z.setFont(font)
        self.checkBox_Z.setObjectName("checkBox_Z")
        # 选择动车
        self.checkBox_D = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_D.setGeometry(QtCore.QRect(300, 5, 80, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.checkBox_D.setFont(font)
        self.checkBox_D.setObjectName("checkBox_D")
        # 选择高铁
        self.checkBox_G = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_G.setGeometry(QtCore.QRect(160, 5, 80, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.checkBox_G.setFont(font)
        self.checkBox_G.setObjectName("checkBox_G")
        # 显示车次类型文字
        self.label_type = QtWidgets.QLabel(self.widget_checkBox)
        self.label_type.setGeometry(QtCore.QRect(20, 5, 80, 25))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_type.setFont(font)
        self.label_type.setObjectName("label_type")

        # -----------------------通过label控件显示火车信息图片--------------------
        self.label_train_img = QtWidgets.QLabel(self.centralwidget)
        self.label_train_img.setGeometry(QtCore.QRect(0, 256, 960, 62))
        self.label_train_img.setStyleSheet("background-image: url(img/bg4.png);")
        self.label_train_img.setText("")
        self.label_train_img.setObjectName("label_train_img")

        # -------------------------查询部分widget--------------------------------------
        self.widget_query = QtWidgets.QWidget(self.centralwidget)
        self.widget_query.setGeometry(QtCore.QRect(0, 140, 960, 80))
        self.widget_query.setStyleSheet("background-image: url(img/bg2.png);")
        self.widget_query.setObjectName("widget_query")
        # 出发地与对应的编辑框控件
        self.label = QtWidgets.QLabel(self.widget_query)
        self.label.setGeometry(QtCore.QRect(30, 20, 70, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.textEdit = QtWidgets.QTextEdit(self.widget_query)
        self.textEdit.setGeometry(QtCore.QRect(100, 20, 110, 30))
        font = QtGui.QFont()  # 创建QFont()对象
        font.setPointSize(13)  # 设置编辑框字体大小的值
        self.textEdit.setFont(font)  # 设置编辑框字体
        self.textEdit.setStyleSheet("background:white;")  # 背景颜色
        # self.textEdit.setTextBackgroundColor(QtGui.QColor("red")) #设置字体背景颜色
        self.textEdit.setObjectName("textEdit")  # 出发地对应编辑框对象名称
        # 目的地与对应的编辑框
        self.label_2 = QtWidgets.QLabel(self.widget_query)
        self.label_2.setGeometry(QtCore.QRect(270, 20, 70, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.textEdit_2 = QtWidgets.QTextEdit(self.widget_query)
        self.textEdit_2.setGeometry(QtCore.QRect(340, 20, 110, 30))
        font = QtGui.QFont()
        font.setPointSize(13)
        self.textEdit_2.setFont(font)
        self.textEdit_2.setStyleSheet("background:white;")  # 背景颜色
        self.textEdit_2.setObjectName("textEdit_2")

        # 出发日与有对应的日期选择框
        self.label_3 = QtWidgets.QLabel(self.widget_query)
        self.label_3.setGeometry(QtCore.QRect(510, 20, 70, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        # 日期选择框
        self.dateEdit = QtWidgets.QDateEdit(self.widget_query)
        self.dateEdit.setGeometry(QtCore.QRect(580, 20, 111, 30))
        font = QtGui.QFont()
        font.setPointSize(-1)
        self.dateEdit.setFont(font)
        self.dateEdit.setStyleSheet("*{font-size:16px}")
        self.dateEdit.setTimeSpec(QtCore.Qt.LocalTime)
        # -------显示时间是当前时间------------
        self.dateEdit.setDate(datetime.date.today())
        # --------设置允许弹出下拉框-----------
        self.dateEdit.setCalendarPopup(True)
        self.dateEdit.setObjectName("dateEdit")

        # 查询按钮
        self.pushButton = QtWidgets.QPushButton(self.widget_query)
        self.pushButton.setGeometry(QtCore.QRect(820, 20, 90, 30))
        self.pushButton.setObjectName("pushButton")

        # -----------------------显示车次信息的列表--------------------------------
        self.tableView = QtWidgets.QTableView(self.centralwidget)
        self.tableView.setGeometry(QtCore.QRect(0, 318, 960, 468))
        self.tableView.setObjectName("tableView")
        self.model = QStandardItemModel();  # 创建存储数据的模式
        # 根据空间自动改变列宽度并且不可修改列宽度
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 设置表头不可见
        self.tableView.horizontalHeader().setVisible(False)
        # 纵向表头不可见
        self.tableView.verticalHeader().setVisible(False)
        # 设置表格内容文字大小
        font = QtGui.QFont()
        font.setPointSize(10)
        self.tableView.setFont(font)
        # 设置表格内容不可编辑
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 垂直滚动条始终开启
        self.tableView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # 主窗体设置主Widget
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)  # 调用retranslateUi方法显示窗体文字
        QtCore.QMetaObject.connectSlotsByName(MainWindow)  # 关联信号槽

        MainWindow.setTabOrder(self.checkBox_G, self.checkBox_D)
        MainWindow.setTabOrder(self.checkBox_D, self.checkBox_Z)
        MainWindow.setTabOrder(self.checkBox_Z, self.checkBox_T)
        MainWindow.setTabOrder(self.checkBox_T, self.checkBox_K)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "12306车票查询-小组成员:王冬、尹翀、卢正刚、王赢杰"))
        self.checkBox_T.setText(_translate("MainWindow", "T-特快"))
        self.checkBox_K.setText(_translate("MainWindow", "K-快速"))
        self.checkBox_Z.setText(_translate("MainWindow", "Z-直达"))
        self.checkBox_D.setText(_translate("MainWindow", "D-动车"))
        self.checkBox_G.setText(_translate("MainWindow", "G-高铁"))
        self.label_type.setText(_translate("MainWindow", "车次类型:"))
        self.label.setText(_translate("MainWindow", "出发地:"))
        self.label_2.setText(_translate("MainWindow", "目的地:"))
        self.label_3.setText(_translate("MainWindow", "出发日:"))
        self.pushButton.setText(_translate("MainWindow", "查询"))
        self.dateEdit.setDisplayFormat(_translate("MainWindow", "yyyy-MM-dd"))

        self.pushButton.clicked.connect(self.on_click)  # 查询按钮指定单击事件的方法
        self.checkBox_G.stateChanged.connect(self.change_G)  # 高铁选中与取消事件
        self.checkBox_D.stateChanged.connect(self.change_D)  # 动车选中与取消事件
        self.checkBox_Z.stateChanged.connect(self.change_Z)  # 直达车选中与取消事件
        self.checkBox_T.stateChanged.connect(self.change_T)  # 特快车选中与取消事件
        self.checkBox_K.stateChanged.connect(self.change_K)  # 快车选中与取消事件

    # 查询按钮的单击事件
    def on_click(self):
        get_from = self.textEdit.toPlainText()  # 获取出发地
        get_to = self.textEdit_2.toPlainText()  # 获取到达地
        get_date = self.dateEdit.text()  # 获取出发时间

        # 判断车站文件是否存在
        if isStations():
            stations = eval(read())  # 读取所有车站并转换为dic类型
            # 判断所有参数是否为空,出发地、目的地、出发日期
            if get_from != "" and get_to != "" and get_date != "":
                # 判断输入的车站名称是否存在,以及时间格式是否正确
                if get_from in stations and get_to in stations:
                    # 获取输入的日期是当前年初到现在一共过了多少天
                    inputYearDay = time.strptime(get_date, "%Y-%m-%d").tm_yday
                    # 获取系统当前日期是当前年初到现在一共过了多少天
                    yearToday = time.localtime(time.time()).tm_yday
                    # 计算时间差,也就是输入的日期减掉系统当前的日期
                    timeDifference = inputYearDay - yearToday
                    # 判断时间差为0时证明是查询当前的查票,
                    # 以及29天以后的车票。12306官方要求只能查询30天以内的车票
                    if 0 <= timeDifference <= 28:
                        from_station = stations[get_from]  # 在所有车站文件中找到对应的参数,出发地
                        to_station = stations[get_to]  # 目的地
                        data = query(get_date, from_station, to_station)  # 发送查询请求,并获取返回的信息
                        self.checkBox_default()  # 取消复选框状态
                        if len(data) != 0:  # 判断返回的数据是否为空
                            # 如果不是空的数据就将车票信息显示在表格中
                            self.displayTable(len(data), 16, data)
                        else:
                            self.messageDialog('警告', '没有返回的网络数据!')
                    else:
                        self.messageDialog('警告', '超出查询日期的范围内,不可查询昨天的车票信息,以及29天以后的车票信息!')
                else:
                    self.messageDialog('警告', '输入的站名不存在,或日期格式不正确!')
            else:
                self.messageDialog('警告', '请填写车站名称!')
        else:
            self.messageDialog('警告', '未下载车站查询文件!')

    # 将所有车次分类复选框取消勾选
    def checkBox_default(self):
        self.checkBox_G.setChecked(False)
        self.checkBox_D.setChecked(False)
        self.checkBox_Z.setChecked(False)
        self.checkBox_T.setChecked(False)
        self.checkBox_K.setChecked(False)

    # 高铁复选框事件处理
    def change_G(self, state):
        # 选中将高铁信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取高铁信息
            g_vehicle()
            # 通过表格显示该车型数据
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_g_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 动车复选框事件处理
    def change_D(self, state):
        # 选中将动车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取动车信息
            d_vehicle()
            # 通过表格显示该车型数据
            self.displayTable(len(type_data), 16, type_data)

        else:
            # 取消选中状态将移除该数据
            r_d_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 直达复选框事件处理
    def change_Z(self, state):
        # 选中将直达车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取直达车信息
            z_vehicle()
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_z_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 特快复选框事件处理
    def change_T(self, state):
        # 选中将特快车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取特快车信息
            t_vehicle()
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_t_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 快速复选框事件处理
    def change_K(self, state):
        # 选中将快车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取快速车信息
            k_vehicle()
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_k_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 显示消息提示框,参数title为提示框标题文字,message为提示信息
    def messageDialog(self, title, message):
        msg_box = QMessageBox(QMessageBox.Warning, title, message)
        msg_box.exec_()

    # 显示车次信息的表格
    # train参数为共有多少趟列车,该参数作为表格的行。
    # info参数为每趟列车的具体信息,例如有座、无座卧铺等。该参数作为表格的列
    def displayTable(self, train, info, data):
        self.model.clear()
        for row in range(train):
            for column in range(info):
                # 添加表格内容
                item = QStandardItem(data[row][column])
                # 向表格存储模式中添加表格具体信息
                self.model.setItem(row, column, item)
        # 设置表格存储数据的模式
        self.tableView.setModel(self.model)


# 显示主窗体
def show_MainWindow():
    app = QtWidgets.QApplication(sys.argv)  # 实例化QApplication,作为GUI主程序入口
    MainWindow = QtWidgets.QMainWindow()  # 创建QMainWindow
    ui = Ui_MainWindow()  # 实例UI类
    ui.setupUi(MainWindow)  # 设置窗体UI
    MainWindow.show()  # 显示窗体
    sys.exit(app.exec_())  # 当窗口创建完成后需要结束主循环


if __name__ == '__main__':
    if not isStations():  # 判断是否有所有车站的文件,没有就下载,有就直接显示窗体
        getStation()  # 下载所有车站文件
        show_MainWindow()  # 调用显示窗体的方法
    else:
        show_MainWindow()  # 调用显示窗体的方法

在这里插入图片描述
在这里插入图片描述
打包为exe方法

  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏至xz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值