先附一张成果图吧
程序框架
设计目的
快期末了,没错,这就是我的期末作业。
因为考试原因,计划用一周的时间来写,写到哪里算哪里嘛 😝 一边上课、一边复习、一边利用课余时间开发,这也就是我一周的成果吧。
本来打算做一个爬虫工具集合软件,做到一半又想利用采集到的数据进行可视化展示或者数据分析,还想自动生成页面部署到服务器上…没错,就是这个原因,导致重构了好几次代码 😢 所以,设计框架之前一定要想好需求!一口气吃不成一个胖子,慢慢积累吧~
主要步骤实现
设计UI(考虑主要功能以及交互方式)
因为以前没有构建大型程序框架的经历,这个程序也算是我的第一个“大型程序”啦 😆 记得听老师说过一句话:“从上而下构建,从下而上实现。”这句话一直指引着我去优化封装、去重构代码。我也确实体会到了一个好的程序框架的重要性。
前台界面怎能不炫酷?!
没错,我找到了QT Design Studio,但是…
太劝退了吧这…
再想一想,python的话,应该对GUI或者前台没有太大的需求,投入过多精力似乎没有太大必要,毕竟就看小程序来讲,Qt的designer已经足够了。于是,我又开始用designer设计界面,然后保存ui文件调用,等等!就是这里,一定要强调下pyside2使用ui文件的两种方法:
1.利用pyside2-uic工具把ui文件转化为python类
命令行输入以下代码
pyside2-uic mainwindow.ui > ui_mainwindow.py
创建类时调用以下代码即可
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
2.动态加载
# 导入QtUiTools模块
from PySide2.QtUiTools import QUiLoader
QUiLoader可以动态加载ui文件并立即使用
ui_file = QFile("mainwindow.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
window = loader.load(ui_file)
window.show()
3.补充:pyqt5中使用方法
# 使用pyuic5转换到py文件
# 使用pyrcc5转化资源文件
# 动态加载
from PyQt5.uic import loadUi
...
loadUi("widget.ui",self)
...
第一次我使用了“动态加载”,这里会有一些bug。例如我们有设置这个程序的主题title,但这里的主题名称却是“Mfgtool”(默认的主题名)。还比如不会触发QMainWindow窗口的事件等等。当然要能接收窗口事件,需要重写对应的事件接口,而且这样重写出来的效果也不是最佳,所以这里不作详细说明了。具体例子:python - PySide2 QMainWindow loaded from ui file not triggering window events - Stack Overflow
所以,采用静态方式加载,这样事件也可以覆盖,非常类似于直接使用Qt IDE开发工具一样方便。
整理子爬虫程序(找到相同点和不同点)
保证子程序可以正常运行的情况下,整合到主程序里。
可以找到不同程序的共同点,例如requests请求,可以封装为get请求,保存数据也可以封装到save函数里。针对不同网址放入不同的类型里面即可,既利于对程序的修改,有利于整理思路脉络,还能减少bug发生的概率。
对不同窗口进行整合
from PySide2.QtWidgets import QApplication, QWidget
#引入主窗口
from mainUI import Ui_mainUI
#引入子窗口
from childUI import Ui_childUI
#创建主窗口类
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
//引入主窗口类
self.ui = Ui_mainUI()
self.ui.setupUi(self)
#创建按钮点击信号连接 其中button是主窗口中的按钮,在主窗口类文件中添加,这里不详细说明
self.ui.button.clicked.connect(self.childShowFun)
#创建子窗口的方法,即槽函数
def childShowFun(self):
#注意,这里的childwindow不能定义成临时变量,必须定义成主窗口类MainWindow的成员变量,'
'如果是临时变量,即前面没有self,那么子窗口只会闪一下,就会消失
self.childwindow = ChildWindow()
self.childwindow .show()
#创建子窗口类
class ChildWindow(QWidget):
def __init__(self):
super(ChildWindow, self).__init__()
#引入子窗口类
self.ui = Ui_childUI()
self.ui.setupUi(self)
if __name__ == "__main__":
app = QApplication([])
mainwindow = MainWindow()
mainwindow.show()
app.exec_()
这是一个子窗口模板,这里也要用静态加载。
⚠注意:如果有多个子窗口,要注意不同模块的函数名是否相同,不然会出现不同槽函数指向同一窗口的现象。我试图通过改文件名,改属性,最后发现进入ui生成的静态py文件更改函数名称是最佳解决方式。
填充小功能
这一阶段主要是查看官方文档,找到相关的函数,之后链接自定义一些相关的槽函数即可。
一些问题与改进
logo的icon文件以及png文件无法打包好还需qrc资源嵌入,也就是涉及到图片的储存与调用,后期修bug和添加小功能时,也许会增加进去吧。
相关资源
程序源码请前往Github
打包程序请前往Alexation(这就是我的主程序名字哦)