让程序走出Terminal。
学习编程最让人兴奋的事之一就是接触到GUI编程,因为那样可以让你的程序不在只是运行在黑乎乎的终端界面,可以拥有图形界面、窗口、按钮等各种各样的元素。
Python中用于GUI编程的模块有很多,比如经典的tkinter
,很多人熟悉的PyQt5
以及wxPython
,如何选择这里不再废话,看标题就知道我用的是PyQt5
了。至于我为什么选择了PyQt5
,一个原因是有很多人推荐,另外一个是它有一个QSS
,类似于前端中的CSS
(层叠样式表),可以对界面的样式进行一些简单的定制。
因为网上的教程也不是很多且多数都一样,所以就挑了一些简单的API来练习一下,练习对象为之前做的翻译程序,为其添加一个简单的GUI。
界面设计
开始前总是要对想写的界面进行一下设计,主要有三个组件,一个输入框(用来输入想翻译的内容),一个显示输出框(用来输出翻译结果),以及一个按钮(用来控制翻译行为)。
Coding
生成一个窗口
第一步需要做到的自然是生成一个窗口出来,编写gui.py文件如下:
1 | import sys |
运行效果如下:
代码说明:
每一个PyQt5
的窗口运行都必须先创建一个QApplication
对象,它负责管理整个图形界面,比如主事件循环,应用程序的初始化和结束等等。创建QApplication
对象需要传递命令行的参数,故使用sys.argv
参数。app.exec_()
方法表示开始主事件循环,当窗口被破坏或结束时该方法返回。
1 | class Window(QWidget): |
自定义了一个Window
类用来封装为翻译程序创建的主窗口,该类继承QWidget
类,QWidget
类是PyQt5中最基本的一个类,它表示窗口中的各种组件,甚至是窗口本身也是一个QWidget
对象,所以创建的这个Window
类要继承QWidget
。
1 | def initUI(self): |
initUI()
方法用来设置主窗口中的各种组件以及相关信息。
setGeometry()
方法设置窗口的位置和大小,单位均为像素,前两个参数代表在屏幕中的位置,即窗口左上角的点位于屏幕中(300px, 300px)的位置,后面两个参数表示宽度和高度。
setWindowTitle()
方法用于设置窗口标题。
show()
方法用于显示窗口。
添加组件
接下来我们要添加三个组件,按钮、输入框和显示框,要用到的类有QtWidget.QPushButton
、QtWidget.QTextEdit
和QtWidget.QTextBrowser
。
1 | import sys |
运行效果:
创建的方法就是创建一个对象的方法,QPushButton
的第一个参数为在按钮中的字符串,第二个参数为它的父组件,这里是self
即主窗口,QTextEdit
和QTextBrowser
只需要传入父组件。
为什么只显示了一个框呢?因为这里只是添加了这三个组件,并没有设置它们的位置,所以它们默认会在窗口左上角也就是(0, 0)的位置创建。
布局
我们需要把组件放到合适的地方,即要进行相应的布局,PyQt5提供的布局方法有很多,比如绝对布局,箱布局,网格布局,表单布局等。这里比较简单,采用箱布局。
首先要思考我们要怎么布局,因为只有三个组件,我们可以分成两行,第一行只有一个居中的按钮,第二行有两个框,即输入框和输出框。
我们把布局考虑成一种对象,这个对象是组件的集合。这里设计到两个类,QVBoxLayout
和QHBoxLayout
类,前者是沿着垂直方向向末尾处添加组件或布局(可以把布局也当做一个组件),后者则是沿水平方向(向右)添加组件或布局。不妨看看代码:
1 | import sys |
运行效果:
QHBoxLayout
和QVBoxLayout
对象的方法一样,addStretch()
方法负责添加一些空白区域,参数表示比例,这个比例是和在这个布局中添加的所有空白的比例,比如hbox
这个布局对象一共添加了两个空白在QPushButton
两侧,且参数均为1,即两个空白的比例为1:1,所以显示的效果为按钮水平居中显示。
addWidget()
负责添加组件到布局中,而addLayout()
则是负责添加一个子布局到布局中,所以说可以把布局也看成一个组件(或者说是组件的集合)。
self.setLayout()
是主窗口用来设置一个主布局的方法。
定制自己的样式
有的时候我们可能不满足于PyQt5的默认样式,比如我们不喜欢按钮的效果,想改变一下它的背景色和字体颜色。这里用到了QSS
(Qt style sheet),即Qt样式表,它的语法与CSS
层叠样式表的语法一样,或者说是CSS
的一个子集(CSS2的子集),它实现了某些CSS
的属性,虽然不是很完全,但起码对按钮的样式修改还是能做到的,工作目录下新建一个window.qss
文件:
1 | QPushButton { |
并在gui.py文件中读取这个文件的内容并加载到样式中:
1 | def initUI(self): |
运行效果:
只要对CSS
语法稍有了解就能写出简单的效果。
导入核心代码
GUI部分基本完成的差不多了,接下来需要导入之前的翻译程序,我们先把翻译程序封装成类:
1 | # youdao.py |
然后在gui.py中导入这个类:
1 | from youdao import Translator |
然后创建一个函数,在按钮被点击的时候回调这个函数:
1 | class Window(QWidget): |
OK!到这里基本就已经完成了我们的目标。运行一下查看效果:
总结
代码在github上。