今天我们就用PyQt5编写一个最基本的windows窗口。
#!/usr/bin/python3
# coding = utf-8
import sys
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
w.resize(250, 150)
w.move(300, 300)
w.setWindowTitle('test1')
w.show()
sys.exit(app.exec_())
import sys
from PyQt5.QtWidgets import QApplication, QWidget
这段代码表明我们引入了python的相关模块,这就包括了sys模块,以及PyQt5中的QtWidgets模块。我们在第一章《我与PyQt5有个约会》中描述了QtWidgets模块包含了一整套UI元素组件,用于建立符合系统风格的classic界面,非常方便。同时为了更方便的使用我们还明确了使用QtWidgets模块中的QApplication, QWidget。我们可以使用help命令看一下。
先将代码展示如下,然后我们细细讲解。
if __name__ == '__main__':
这个属于Python基础知识,如果写了这句话并将执行的语句放到这个判断语句的后面,那么只有在程序本身被执行的时候才能运行这个判断语句下面的语句。否则程序被作为模块导入的时候就会执行。
app = QApplication(sys.argv)
每个PyQt5应用程序必须创建一个应用程序对象。 sys.argv参数是来自命令行的参数列表。 Python脚本可以从shell运行。 写了这句话就能让我们的程序从命令行启动。
w = QWidget()
QWidget小部件是PyQt5中所有用户界面对象的基类。 我们提供了QWidget的默认构造函数。 默认构造函数没有父类。 没有父类口小部件称为窗口。
w.resize(250, 150)
resize()方法调整窗口小部件的大小。这里我们设定窗口的大小:宽250像素,高150像素。
w.move(300, 300)
move()方法将小部件移动到屏幕上x = 300,y = 300坐标处的位置。
w.setWindowTitle('test1')
设置窗口的标题
w.show()
show()方法在屏幕上显示窗口小部件。 一个小部件首先在内存中创建,然后在屏幕上显示。
sys.exit(app.exec_())
最后,我们进入应用程序的主循环(main loop)。 事件处理从这一点开始。 主循环(main loop)从窗口系统接收事件并将它们分派到应用程序小部件。 如果我们调用exit()方法或者主窗口小部件被破坏,那么主循环(main loop)就会结束。
sys.exit()方法确保一个干净的退出。
exec_()方法有一个下划线。 这是因为exec是一个Python关键字。 因此,使用exec_()。
GUI应用程序都是事件驱动的。比如键盘事件、鼠标事件等等。还有一些事件来自于系统内部,比如定时事件、其它文件事件等等。在没有任何事件的情况下,应用程序处于睡眠状态。这种事件驱动机制,GUI应用程序都需要一个主循环(main loop)。主循环(main loop)控制应用程序什么时候进入睡眠状态,什么时候被唤醒。所以主循环(main loop)就是干这个的。
上面的代码基本上是按照面向过程来写的,下面开始我们采用面向对象的方式进行编码。
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
class Ico(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('test2')
self.setWindowIcon(QIcon('icon.ico'))
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Ico()
sys.exit(app.exec_())
from PyQt5.QtGui import QIcon
从PyQt5.QtGui中引入QIcon这个类,也是为了便于图标的设定。
class Ico(QWidget):
def __init__(self):
super().__init__()
self.initUI()
我这里继承了QWidget这个基类,并自定义了一个名为Ico的新类。同时对这个Ico的新类进行了初始化。
举一个例子说明面向对象编程中的继承概念:
class OldDog():
def __init__(self):
print('I am an old dog !')
self.hungry = True
def eat(self):
if self.hungry:
print('I eat it !')
self.hungry = False
else:
print('No thanks!')
class NewDog(OldDog):
def __init__(self):
super().__init__()
print('I am a new dog!')
olddog = OldDog()
olddog.eat()
olddog.eat()
newdog = NewDog()
newdog.eat()
newdog.eat()
结果:
从上面这个例子我们可以知道,当子类继承父类的时候,我们继承了父类的方法。子类中含有__init__时,不会自动调用父类__init__,如需使用父类__init__中的变量,则需要在子类__init__中显式调用。
说的好复杂,其实就是一点,我们要用QWidget中__init__的变量,就必须在子类Ico中显示调用:super().init()。__init __()方法是Python语言的初始化方法(构造函数)。
self.initUI()
程序的GUI界面用initUI()函数创建。
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('test2')
self.setWindowIcon(QIcon('icon.ico'))
上面的三种方法都已经从QWidget类中继承的。 setGeometry()做了两件事情:它在屏幕上定位窗口并设置它的大小;前两个参数是窗口的x和y位置;第三个是宽度;第四个是窗口的高度。实际上,它在一个方法中组合了resize()和move()方法。 最后一个方法设置应用程序图标。 为此,我们创建了一个QIcon对象。 QIcon接收到我们要显示的图标的路径(和当前程序在同一个目录下)。
接下我们再这个窗口增加一个关闭按钮并实现关闭窗口的功能。
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QCoreApplication
class Ico(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('test4')
self.setWindowIcon(QIcon('icon.ico'))
qbtn = QPushButton('退出', self)
qbtn.clicked.connect(QCoreApplication.instance().quit)
qbtn.resize(70, 30)
qbtn.move(50, 50)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Ico()
sys.exit(app.exec_())
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import QCoreApplication
因为需要增加按钮,所以我们引入了QPushButton类。同时我们还需要一个来自QtCore模块的对象。
qbtn = QPushButton('Quit', self)
我们创建一个按钮。该按钮是QPushButton类的一个实例。构造函数的第一个参数是按钮的标签。第二个参数是父窗口小部件。父窗口小部件是示例窗口小部件,它是通过QWidget继承的。
qbtn.clicked.connect(QCoreApplication.instance().quit)
PyQt5中的事件处理系统采用信号和槽机制构建。 如果我们点击按钮,点击的信号被发出。 槽可以是Qt槽函数或任何Python可调用的函数。 QCoreApplication包含主事件循环; 它处理和调度所有事件。 instance()方法给我们当前的实例。
注意,QCoreApplication是通过QApplication创建的。 点击的信号连接到终止应用程序的quit()方法。
通信在两个对象之间完成:发送方和接收方。 发送方是按钮,接收者是应用对象。
简单的来说就是按钮发出被单击的信号,连接到退出程序的方法。
参考文献:https://zhuanlan.zhihu.com/p/28130949