最近在Boss直聘上找工作,看到很多的爬虫工作上都有”能够一键爬虫”这一要求,我觉得有这个要求可能是考虑到用户的水平吧,既然如此,我想用户也不一定能看得习惯命令行,还是给用户一个方便的UI界面比较好。虽然因为种种原因没有去实际工作(这里感谢提供给我机会的喵房科技的范毓魁经理),不过要学习GUI这事我却记下了。之前曾有想法,想要直接使用HTML页面来控制程序,这样不但方便,也省下学习GUI花费的时间了。
然而想法是美好的,HTML也可以让用户在本地访问,但是你都打开浏览器了,那网页不弄得美观点有点说不过去吧?但是鉴于本人的前端技术实在太烂,终于还是选择了学习Gui编程。
这里使用的是PyQt5,见网上有人说这个性能高,于是就打算学这个了。那么闲聊到此结束,下面先来一道基本程序。
演示效果
先看演示效果:
那么下面上代码:
1 | from PyQt5.Qt import * # Qt模块包含了常用的包和模块 |
这里我使用的Linux系统的XFCE4桌面,由于我是仿MacOS美化,所以成了红绿灯,不要在意这些细节,如果你是Windows系统的话它会自动变成最小化,最大化,关闭窗口。
关于sys.argv
那么我先说一下sys.argv是什么意思,看代码:
1 | import sys |
运行这段代码:
1 | python3 test2.py |
这次我们在脚本执行的时候带上一些参数:
1 | python3 2test.py 1 2 3 |
那么这下就理解了,sys.argv是用来接收参数的,其会返回一个列表,且第一个元素为该文件的路径。然而这里有些理解不能的是,如果使用Pycharm的右击Run运行,输出的路径是绝对路径,如:[‘/home/fire/projectset/PythonGui/2test.py’]。而如果直接使用终端,那么输出的就是如上的内容了。
关于sys.exit(app.exec_())
接着我再来解释一下sys.exit()的意思,sys.exit()是用来退出的,它可以接收一个状态码,用来返回程序退出的状态,如果程序正确执行,那么其值应该为0。
然后我们知道,有个叫做:”一般顺序结构”的东西,它规定了程序的执行的顺序。在Python中,执行顺序应该是这样的: 先执行第一行,再执行第二行,再第三行…. 那么我们既然都sys.exit()了,窗口为什么没有退出呢?就是因为有app.exec_()阻止了它。你可以试一下,把app.exec_()删掉,然后运行一下脚本,就会看到一个窗口一闪而过,而后程序结束。而加上它,程序会在不崩溃的情况下持续到你手动退出,如果崩溃了则会返回状态码。需要注意的是,如果你没有加sys.exit(app.exec_())这行代码,那么窗口也会一闪而过。
所以这个app.exec_()到底是什么神奇的东西呢?它的意思是让程序进入主循环,不要停止(别人的课件上是这么说的),流程应该是:创建一个应用程序对象(app = QApplication()),执行应用程序对象(app.exec_())。而关于app.exec_我Google到了这么一句话: # Your application won’t reach here until you exit and the event. 所以大概就是这么个意思吧。
关于程序参数
先来看一段代码:
1 | import sys |
执行这段代码:
1 | python3 2test.py 1 2 4 |
可以看到,给QApplication传入的参数,可以被arguments()方法取出来。而如果是两个不同的py脚本,它们之间应该怎么传递参数呢?PyQt5.QtWidgets里有这么一个变量:qApp,从PyQt5.Qt中也可以导入它。那么它的作用是什么呢?使用Pycharm按住Ctrl键左击它,可以发现有这么一行代码:
1 | qApp = QApplication() # real value of type <class 'PyQt5.QtWidgets.QApplication'> replaced |
你可以把这货当成一个全局的变量。
看下面的代码:
1 | import sys |
运行:
1 | python3 2test.py 1 2 4 |
这样就理解了吧。
关于控件的操作
控件的操作是这么个流程:创建控件–>设置控件–>展示控件。如果一个控件没有父级控件,这个控件就会被视为是顶层控件,会自动被加上窗口标题,关闭窗口等模块。如果有父控件的话,那么父控件会被视为容器,其会在父控件内部展示。如果你一个程序设置了两个顶层控件,那么当你展示这两个控件的时候,就会出现两个窗口。代码如下:
1 | import sys |
这里因为我现在的操作系统截图不便的缘故(因为我使用的GIMP截图,所以面对两个窗口的情况就有些蛋疼了)就不放图片效果了。代码中有两个show()方法的调用,删掉任意一个,就只会展示出一个窗口。因为它们都是顶层控件,所以在调用show()方法的时候都会被视为独立的窗口。
那么接下来就演示一下父控件:
1 | import sys |
在这段代码中我们将QWidget作为QLabel的父控件,将其作为参数传入QLabel()中,展示的时候我们只需展示父控件即可。
下面是效果: