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

Qt5 Python GUI 编程指南

多级继承的使用

多级继承是一个类继承自另一个单独的类。这个继承的类又依次被第三个类继承,如下图所示:

从上面这副图中,你可以看到类B继承了类A,并且类C又依次继承自类B。

下面的语句定义了多级继承,这个Result类继承了Marks类,而这个Marks类又依次继承了Student类:

class Student:
	class Marks(Student):
        class Result(Marks):

在前面的语句中,Student是基类,并且Marks类继承自Student类。而Result类又继承自Marks类。因此,Result类的实例可以访问Marks类中的变量和方法,并且Marks实例可以访问Student类中的变量和方法。

准备

为了理解多级继承的概念,让我们创建一个应用程序,它将提示用户输入学号、姓名、历史分数和地理分数,并在单击按钮时显示总分数和百分比。总分数将是历史分数和地理分数的总和。假设最大分数为100,计算百分比的公式为:总分数/200 * 100。

用户输入的学号和姓名会被赋给Student类的类变量。历史和地理分数将被赋给另一个Marks的类的成员。为了访问学号和姓名还有历史和地理分数,这个Marks类将需要继承自Student类。使用多级继承,那么这个Marks类的实例将可以访问Student类中的学号和姓名。为了计算总分数和百分比,需要再使用一个名为Result的类。这个Result类将继承自Marks类。因此,这个Result类的实例可以访问Marks类中的类成员,包括Student类中的成员。这个Result类有两个类成员:totalMarks 和 percentage。totalMarks类成员会被赋于Marks类中historyMarks 与 geographyMarks 成员的和。百分比成员将被赋于基于历史与地理分数所需要的百分比。

如何去做...

总之,有三个类分别为Student,Marks和Result,Result类继承自Marks类,而Marks类又依次继承自Student类。因此,Result类的成员可以访问Marks类中的成员和Student类中的成员。这里是一步一步创建应用程序的过程:

  1. 运行Qt Designer并基于Dialog without Buttons模板新建一个应用程序。

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

  3. 将这6个Label部件的text属性分别设置为Student Code,Student Name,History Marks,Geography Marks,Total和Percentage。

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

  5. 将6个Line Edit部件的objectName属性分别设置为lineEditCode,lineEditName,lineEditHistoryMarks,lineEditGeographyMarks,lineEditTotal和lineEditPercentage。

  6. 将Push Button部件的objectName属性设置为ButonClickMe。

  7. 通过取消选中 Perperty Editor 窗中的 Enable 属性来禁用 lineEditTotal 和 lineEditPercentage框。禁用lineEditTotal 和 lineEditPercentage部件是因为这些输入框将通过代码进行赋值,并且我们不想让它们的值被用户更改。

  8. 将应用保存为demoMultilevelInheritance.ui。这个应用看起来如下截图所示:

    这个用户界面文件demoMultilevelInheritance.ui是一个XML文件,需要通过pyuic5工具将其转换成Python代码。你可以在本书源代码中看到这个生成的Python脚本文件demoMultilevelInheritance.py。这个demoMultilevelInheritance.py 文件将作为头文件导入到其它需要调用其GUI的Python脚本文件中。

  1. 创建另一个名为callMultilevelInheritance.pyw的Python文件并导入demoMultilevelInheritance.py代码。callMultilevelInheritance.pyw 的Python脚本中的代码如下所示:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from demoMultilevelInheritance 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 Marks(Student):
    historyMarks = 0
    geographyMarks = 0
    def __init__(self, code, name, historyMarks,
        geographyMarks):
        Student.__init__(self,code,name)
        self.historyMarks = historyMarks
        self.geographyMarks = geographyMarks
    def getHistoryMarks(self):
        return self.historyMarks
    def getGeographyMarks(self):
        return self.geographyMarks
class Result(Marks):
    totalMarks = 0
    percentage = 0
    def __init__(self, code, name, historyMarks,
        geographyMarks):
        Marks.__init__(self, code, name, historyMarks,
        geographyMarks)
        self.totalMarks = historyMarks + geographyMarks
        self.percentage = (historyMarks +
        geographyMarks) / 200 * 100
    def getTotalMarks(self):
        return self.totalMarks
    def getPercentage(self):
    	return self.percentage
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):
        resultObj=Result(self.ui.lineEditCode.text(),
        self.ui.lineEditName.text(),
        int(self.ui.lineEditHistoryMarks.text()),
        int(self.ui.lineEditGeographyMarks.text()))
        self.ui.lineEditTotal.setText(str(resultObj.
        getTotalMarks()))
        self.ui.lineEditPercentage.setText(str(resultObj.
        getPercentage()))
if __name__=="__main__":
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

它是如何工作的...

在前面callMultilevelInheritance.pyw文件的代码中,你可以看到定义了一个Student类。这个Student类包含两个名为name和code的类变量,还有三个方法如下所示:

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

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

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

Marks类继承自Student类。因此,Marks类的实例不仅可以访问它自身的成员,还可以访问Student类中的成员。

Marks类中包含两个类变量,分别为historyMarks和geographyMarks,还包括以下三个方法:

  • __init()__:这是一个构造函数,它带有一个必需的参数和另外4个参数,分别为code、name、historyMarks和geographyMarks。在这个构造函数中,调用Student构造函数并传入code和name这两个参数。historyMarks 和 geographyMarks 这两个参数用于初始化 historyMarks 和 geographyMarks这两个类成员。

  • getHistoryMarks():这个方法简单的返回 historyMarks 类变量的值。

  • getGeographyMarks():这个方法简单的返回 geographyMarks 类变量的值。

这个Result类继承自Marks类。Result类的实例不仅可以访问它自己的成员,还可以访问Marks类和Student类中的成员。

Result类包含两个类变量,分别为totalMarks和percentage,还有三个方法如下所示:

  • __init()__:这是一个构造函数,带有一个必需的 self 参数和另外4个参数,分别为code,name,historyMarks 和 geographyMarks。在这个构造函数中调用Marks类的构造函数并传入code,name,historyMarks和geographyMarks参数。historyMarks与geographyMarks这两个类变量的和会赋给totalMarks类变量。假设每科最高分数是100,那么将计算的历史与地理分数的百分比赋给percentage类变量。

  • getTotalMarks():这个方法简单返回historyMarks类变量的值。

  • getPercentage():这个方法简单返回历史与地理分数的百分比。

Push Button部件的clicked()事件与dispmessage()方法关联。在Line Edit部件中输入学号,姓名,历史分数和地理分数后,当用户单击按钮时,就会调用dispmessage()方法。这个dispmessage()方法定义了名为resultObj的Result类的对象,并将用户在Line Edit部件中输入的学号、姓名、历史和地理分数作为参数传入。调用Result类的构造函数 __init()__ 并将用户输入的学号、姓名、历史与地理分数作为参数传入。在Result类的构造函数中,调用了Marks类的构造函数,并传入学号、姓名、历史分数和地理分数参数。在Marks类构造函数中调用Student构造函数并传入code和name参数。在Student类构造函数中,将code与name参数分别赋给code和name的类变量。类似的,将历史与地理分数分别赋给Marks类中的historyMarks和geographyMarks类变量。

将historyMarks和geographyMarks的和赋给tatalMarks类变量。此外,将计算的历史与地理分数的百分比赋给percentage类变量。

之后,设置名为lineEditTotal的Line Edit部件以显示总分数,即调用resultObj对象中getTotalMarks()方法计算得到的历史与地理的分数和。此外,设置名为lineEditPercentage的Line Edit部件以显示分数百分比,这个百分比是通过调用resultObj对象中的getPercentage()方法得到的。

因此,单击按钮,名为 lineEditTotal 和 名为 lineEditPercentage的Line Edit部件将分别显示总分和用户输入的历史与地理分数的百分比,如下截图所示: