PYTHON 实现 NBA 赛程查询工具(一)—— pyqt界面

前言:

第一篇博客,记录一下最近的一点点小成果。

一切的学习都从兴趣开始。最近忽然想学习一下 pyqt 和 python 的网络爬虫知识,于是就自己找了一个课题做了起来。因为我正好是个 NBA 球迷,就想到了通过网络爬虫来抓取比赛结果,方便本地进行查找的项目。


这个项目总共分为三步:

1. 界面制作

选择对应的球队,显示球队图标和比赛结果

2. 网络爬虫

访问特定网页,查找赛季至今的比赛结果信息,并保存到本地作为待查找的文件

3. 工具打包

将上述两部分联调,并生成 exe 工具直接调用

我预备从以上三个部分,分别记录该查询工具的实现过程。


界面制作:

界面制作一直都想学,发现 pyqt 这个工具非常的顺手,可以通过直接拖拽模块来画界面。为了描述专业点,下面均称之为 Qt designer。

 

1. 界面设计:

下面先直接把最后设计的界面和效果图展示,然后挑几个值得一提的模块简单介绍一下:

 

QComboBox:产生下拉菜单的模块。下拉菜单中的可选项均可通过双击模块添加。被选中之后会产生一个“currentIndexChanged()”事件,根据这个时间去修改二级菜单中的对应项。

QLabel:用于显示查找结果。原先使用的是QLineEdit,由于自带一个鼠标靠近变色的事件,后来就用QLabel代替,QLabel还没有边框,在生成界面的时候显得简洁。

QLabel是一个非常好用的模块,界面中的VS字样,显示比分、球队图标、比赛时间,还有查询工具那张图,均是用QLabel实现的。

Layout:用于排版。将多个图标以整齐的方式排布在一起。整个结果栏使用了一个大的横向Layout,每一个小的比分又用了小的纵向Layout放置球队图标,比分等信息。

 

剩下的就是如何编排,让界面显得美观,这个就见仁见智了。

    

图1 NBA比赛查询系统界面


2. 生成代码:

将生成的 .ui文件转换成python可以运行的代码,有一条专门的指令,以我的这个工具为例:

pyuic4 -o NBA_schedule_2.py -x NBA_schedule_2.ui

这样就可以将 .ui文件变成 .py文件来运行。

将这条指令写成了批处理文件,每次修改完界面文件之后,执行一下即可。直接运行此py文件,就可以得到相应的界面。

这步中生成的代码由于会随着每次修改界面文件而改变,所以在文件在直接修改是很不明智的,以后修改起来也会很麻烦。最好的方法是将此文件作为模块,用另一个py文件去调用里面的类。


3. 功能实现:

新建一个类,继承ui生成的界面文件中的类,在新的类中定义信号。

本工具中有三个信号:

(1) 开始查询信号

(2) 客队赛区选定信号

(3) 主队赛区选定信号

当赛区选定之后,QComboBox会产生一个 currentIndexChanged 的信号,程序接收这个信号,对二级菜单进行修改,即重新加载球队。

点击“GO”按钮,开始查询交手情况。会将比分和球队logo显示在界面上,尚未开始的比赛只显示球队logo,标识主客。

 

功能一:选择球队

加载二级菜单,是利用QComboBox的信号,并再利用QComboBox的方法填充内容。

if roadteam_district == u'太平洋赛区':
    self.RoadTeam_combo.setItemText(0, _translate("Dialog", "太阳", None))
    self.RoadTeam_combo.setItemText(1, _translate("Dialog", "勇士", None))
    self.RoadTeam_combo.setItemText(2, _translate("Dialog", "湖人", None))
    self.RoadTeam_combo.setItemText(3, _translate("Dialog", "快船", None))
    self.RoadTeam_combo.setItemText(4, _translate("Dialog", "国王", None))

由于填入QComboBox的内容不是str格式,因此做了一个_translate转换。转换方式在生成界面py文件的时候会一并生成,并不需要自己编写代码。

 

功能二:查找比赛结果

查询交手情况先从本地的一个.csv文件开始查询,.csv每一行的存放可以事先规定好,这是要从网页端爬取下来的,因此格式可以自己规定。当前采取的格式是“客队,主队,比分,比赛时间”。

用QComboBox的currentText方法获取待查询的球队名称。由于读到的格式并不是字符串,将其转成字符串之后,再进行查询。

最开始的工具区分主队客队,两队主客交换会认为是另一组结果,随后将主客队的查询方式去掉,只查询两支球队的相互战绩,在显示的时候采取左边客队,右边主队的显示方式。寻找的范围以常规赛为主,因此最多有四场交手记录,也可以就此规定界面的长度。常规赛开始时间是2017年10月18日,因此比赛时间小于20171018的比赛,均不会纳入查找范畴。

 

功能三:加载球队logo

由于从.csv文件中读出的球队,是按照先客后主的顺序,所以可以将读到文件中的第一个值作为客队名,第二个值作为主队名,依照队名,到对应的字典中寻找图片地址,并加载到界面中。

NBA_LOGO_DICT = {u'火箭':'./NBA_team/HOU.png', u'马刺':'./NBA_team/SAS.png', u'鹈鹕':'./NBA_team/NOP.png', u'灰熊':'./NBA_team/MEN.png', u'小牛':'./NBA_team/DAL.png',
            u'勇士':'./NBA_team/GSW.png', u'湖人':'./NBA_team/LAL.png', u'快船':'./NBA_team/LAC.png', u'太阳':'./NBA_team/PHX.png', u'国王':'./NBA_team/SAC.png',
            u'开拓者':'./NBA_team/POR.png', u'森林狼':'./NBA_team/MIN.png', u'掘金':'./NBA_team/DEN.png', u'雷霆':'./NBA_team/OKC.png', u'爵士':'./NBA_team/UTA.png',
            u'凯尔特人':'./NBA_team/BOS.png', u'猛龙':'./NBA_team/TOR.png', u'76人':'./NBA_team/PHI.png', u'尼克斯':'./NBA_team/NYK.png', u'篮网':'./NBA_team/BKN.png',
            u'奇才':'./NBA_team/WAS.png', u'热火':'./NBA_team/MIA.png', u'黄蜂':'./NBA_team/CHA.png', u'魔术':'./NBA_team/ORL.png', u'老鹰':'./NBA_team/ATL.png',
            u'活塞':'./NBA_team/DET.png', u'骑士':'./NBA_team/CLE.png', u'步行者':'./NBA_team/IND.png', u'雄鹿':'./NBA_team/MIL.png', u'公牛':'./NBA_team/CHI.png'}


球队名称均用utf-8格式编码。搜索到多少场比赛,加载多少个图标,包括未开赛的。未开赛的比赛加载图标,可以显示主客情况。

 

功能四:修改界面字体颜色大小

由于任意两队之间的比赛场次不固定,如果这赛季只打两场比赛,但是加载出了4个框,会显得非常冗余,应该根据实际比赛的场次,来加载相应数目的对战框。

在每次搜索开始之前,会先将上次的框清空。

        for i in range(4):
            self.r_pic_list[i].setPixmap(QtGui.QPixmap(_fromUtf8(None)))
            self.h_pic_list[i].setPixmap(QtGui.QPixmap(_fromUtf8(None)))
            self.game_list[i].setStyleSheet(_fromUtf8("font: 16pt \"微软雅黑\";"))
            self.game_list[i].setText(_translate("Dialog", '', None))
            self.score_list[i].setText(_translate("Dialog", '', None))

其中r_pic_list,h_pic_list,game_list,score_list为自行创建的列表

        self.score_list = [self.Score1_label, self.Score2_label, self.Score3_label, self.Score4_label]
        self.game_list  = [self.GameDay1_label, self.GameDay2_label, self.GameDay3_label, self.GameDay4_label]
        self.r_pic_list = [self.RoadTeam_pic_1, self.RoadTeam_pic_2, self.RoadTeam_pic_3, self.RoadTeam_pic_4]
        self.h_pic_list = [self.HostTeam_pic_1, self.HostTeam_pic_2, self.HostTeam_pic_3, self.HostTeam_pic_4]

之后再行加载搜索到场次数目的比赛结果。

 

比分框用白色背景,黑色字体,字号规定为20号。加载比分时,直接将比分数字写入框内即可。

比赛时间框用蓝色背景,白色字体,字号为14号。在未加载比赛结果时,希望蓝色背景不显示,因此在清空框内内容时,重新设置了label框,清除了背景色。再次加载比赛时间,才限定背景色等等。

        for i in range(len(result_list)):
            r_t = "%s" %result_list[i][0]
            h_t = "%s" %result_list[i][1]
            self.r_pic_list[i].setPixmap(QtGui.QPixmap(_fromUtf8(NBA_LOGO_DICT[r_t])))
            self.h_pic_list[i].setPixmap(QtGui.QPixmap(_fromUtf8(NBA_LOGO_DICT[h_t])))
            self.game_list[i].setStyleSheet(_fromUtf8("background-color: rgb(100, 200, 200);\n"
                                                        "color: rgb(255, 255, 255);\n"
                                                        "font: 14pt \"微软雅黑\";"))
            self.game_list[i].setText(_translate("Dialog", result_list[i][3], None))
            self.score_list[i].setText(_translate("Dialog", result_list[i][2], None))

至此,界面端功能大致介绍完毕。

完整程序可参考以下链接:点我


相关链接:

PYTHON 实现 NBA 赛程查询工具(二)—— 网络爬虫

PYTHON 实现 NBA 赛程查询工具(三)—— 工具打包

猜你喜欢

转载自blog.csdn.net/panfengzjz/article/details/78878661