Qt5 Python GUI 编程指南
创建时间:2018-12-10  访问量:5955  7  0

Qt5 Python GUI 编程指南

GUI中类的使用

数据是用户通过GUI获取的,它可以通过简单的使用变量来直接传递,传入的数据仅可以通过变量来显示。但为了保存结构化的数据,可以从OOP中获益,我们将学习以类的形式保存变量。也就是说,数据是由用户通过GUI访问的,它可以赋值给类的变量后处理再通过类的方法显示出来。

让我们创建一个应用,提示用户输入名称,之后单击按钮,应用将利用名称显示一个欢迎消息。名称是通过用户输入的,被赋值给一个类变量,并且欢迎消息也是由类中的类方法生成的。

如何去做...

本节关注的是理解数据是如何由用户输入并赋值给类变量的,消息是如何通过类方法访问的。让我们基于Dialog without Buttons 模板创建一个应用应程,步骤如下:

  1. 拖动 2 个Label部件,1个Line Edit和 1 个Push Button部件放到窗体上。

  2. 将第1个Label部件的text属性设置为Enter your name。

我们不改变第2个Label部件的text属性,并且将其保持为TextLable的黙认值。这是因为它的文本将会通过代码来显示欢迎消息。

  1. 将Push Button部件的text属性值设置为Click。

  2. 将Line Edit部件的objectName属性值设置为lineEditName。

  3. 将Label部件的objectName属性值设置为labelResponse。

  4. 将Push Button部件的objectName属性值设置为ButtonClickMe。

  5. 将应用保存为LineEditClass.ui。这个应用的显示如下截图所示:

    

    用户界面是由Qt Designer创建的并保存在一个.ui的XML文件中,这个XML文件需要转换成Python代码。

  1. 为了转换,你需要打开命令提示窗口,导航到这个文件保存的路径,并执行下面的命令:

    C:\Pythonbook\PyQt5>pyuic5 LineEdit.uiClass -o LineEditClass.py

    生成的Python脚本为LineEditClass.py,可以在本书源码中找到。

  2. 将前面的代码作为头文件,并导入到需要调用用户界面的脚本文件中。

  3. 创建另一个名为callLineEditClass.pyw的Python文件,并导入LineEditClass.py代码,如下所示:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from LineEditClass import *
class Student:
    name = ""
    def __init__(self, name):
    	self.name = name
    def printName(self):
        return self.name
class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.ButtonClickMe.clicked.connect(self.dispmessage)
        self.show()
    def dispmessage(self):
        studentObj=Student(self.ui.lineEditName.text())
        self.ui.labelResponse.setText("Hello
        "+studentObj.printName())
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

它是如何工作的...

在LineEditClass.py文件中,有一个使用UI_开头的具有顶层对象名的类。也就是说,使用顶层的对象Dialog,创建了Ui_Dialog类并存储了用户界面中的部件元素。这个类有两个方法,setupUi()和retranslateUi()。这个setupUi()方法用于创建用户在Qt Designer中定义的部件。此外,部件的属性都是通过这个方法设置的。这个setupUi()方法只有一个参数,就是应用的顶层部件,即一个QDialog的实例。这个retranslateU()方法会用来转换界面。

在callLineEditClass.py文件中,你可以看到定义了一个Student类。这个Student类包含一个name的类变量,有下面两个方法:

  • __init()__:这是一个构造函数,必须传入self参数和一个name参数,这个name参数用于初始化name类变量的。

  • printName:这个方法简单返回name类变量的值。

Push Button部件的clicked()事件与dispmesage()方法相关联;在Line Edit部件中输入名称之后,当用户单击按钮时,就会调用dispmessage()方法。这个dispmessage()方法定义了一个Student类的对象,名为studentObj,并将用户在Line Edit部件中输入的内容作为参数传入。因此,Student类的构造函数将会被调用并将用户输入的名称传给此构造函数。Line Edit部件中输入的名称将会被赋给类变量name。在那之后,Label部件会调用labelResponse 设置显示的字符串hello,并调用Student类中的printName方法,它会返回name变量。因此,在单击按钮后,Label部件就会显示hello字符串,后面跟上用户在Line Edit框中输入的名称,显示结果如下截图所示:

让应用程序更精制

我们也可以在类中使用两个或更多个类属性。

我们假设除了类名Student,还要向类中添加学生的代码。在这种情况下,我们需要向类中添加更多的属性,可以添加code属性和getCode()方法,这个方法用于访问学生号。除了这个类,还要修改GUI。

我们需要另外向应用程序中添加一些Label部件和一个Line Edit部件,并将应用保存为另一个名称demoStudentClass。在添加了Label和Line Edit部件之后,用户界面看起来如下面的截图所示:

用户界面文件demoStudentClass.ui,需要转换成Python代码。生成的Python脚本文件demoStudentClass.py可以在本书源码中找到。

让我们来创建另一个名为callStudentClass.pyw的Python脚本文件并导入demoStudentClass.py代码。callStudentClass.pyw中的代码如下所示:

 

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from demoStudentClass import *
class Student:
    name = ""
    code = ""
    def __init__(self, code, name):
        self.code = code
        self.name = name
        def getCode(self):
        return self.code
    def getName(self):
    	return self.name

class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.ButtonClickMe.clicked.connect(self.dispmessage)
        self.show()
    def dispmessage(self):
        studentObj=Student(self.ui.lineEditCode.text(),
        self.ui.lineEditName.text())
        self.ui.labelResponse.setText("Code:
        "+studentObj.getCode()+", Name:"+studentObj.getName())
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

在上面的代码中,你看到了一个名为Student的类。这个Student类包含了两个类变量name和code。除了这两个类变量之外,这个Student类还包含下面三个方法:

  • __init()__:这是一个带有必须的self参数的构造函数并有另两个参数,code和name,这些参数用于初始化code和name这两个类变量

  • getCode():这个方法简单的返回类变量code的值

  • getName():这个方法简单的返回类变量name的值

Push Button部件的clicked()事件与dispmessage()方法相关联;在Line Edit部件中输入code和name之后,当用户单击按钮时,就会调用dispmessage()方法。这个dispmessage()方法中定义了Student类的名为studentObj的对象,并将用户在Line Edit中输入的code和name作为参数传入。Student类的构造函数 __init()__将被调用并且向其传入输入的code和name参数。这个输入的code和name将被分别赋值给code和name类变量。在那之后,Label部件就会调用 labelResponse 通过调用Studen类的studentObj对象中的getCode和getName这两个方法来显示code和name。

因此,单击按钮,Label部件就会显示用户在Line Edit部件中输入的code和name的值了,显示如下面的截图所示:

继承

继承的概念是一个已存在类中的方法和变量可以在另一个类中复用,而不需重新写代码。也就是说,已存在的测试和运行的代码可以立即在其它的类中被复用。

继承的类型

有三种继承类型,如下所示:

  • 单继承(Single inheritance):一个类继承于另一个类

  • 多级继承(Multilevel inheritance):一个类继承另一个,而另一类又会继承自其它一些类

  • 多继承(Multiple inheritance):一个类继承自两个或更多个类