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

Qt5 Python GUI 编程指南

多继承的使用

多继承是一个类继承两个或两个以上的类,如下图所示:

类C继承了两个类,分别为类A和类B。

下面的语句定义了多继承,Result类继承了Marks类和Student类:

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

在前面的语句中,Student和Marks都是基类,而Result类继承了Student和Marks这两个类。因此,Result类的实例可以访问Marks和Student类中的变量和方法。

准备

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

学号和姓名由学生输入并赋给Student类的类成员。历史和地理分数将被赋给另一个Marks类中的类成员。

为了访问学号和姓名,还有历史和地理的分数,这个Result类将继承这两个类,即Student类和Marks类。使用多继承,Result类的实例就可以访问Student类中的学号和姓名,也可以访问Marks类中的historyMarks和geographyMarks类变量。换句话说,使用多继承,Result实例可以访问Marks类和Student类中的成员。这个Result类有两个类成员,分别为totalMarks和percentage。将Marks类中的historyMarks和geographyMarks成员的和赋给totalMarks类变量。将基于历史与地理分数计算的百分比赋给percentage成员。

如何去做...

让我们通过一步步的过程来理解多继承是发何应用Student、Marks和Result这三个类的。这个Result类将同时继承Studnet和Marks这两个类。这些步骤解释了Result类中的这些成员是如何通过多继承来访问Student和Marks类中的成员的:

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

  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部件的ojbectName属性分别设置为lineEditCode,lineEditName,lineEditHistoryMarks,lineEditGeographyMarks,lineEditTotal 和 lineEditPercentage。

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

  7. 通过取消选中Property Editor窗口中的Enable属性以禁用lineEditTotal和lineEditPercentage这两个框,因为将要通过代码为其赋值,并且我们不想让用户更改它们的值。

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

    用户界面文件demoMultipleInheritance.ui是一个XML文件并使用pyuic5命令将其转换成Python代码。你可以在本书源码中找到生成的Python代码demoMultipleInheritance.py。这个demoMultipleIneritance.py文件将作为头文件导入到其它需要调用此代码创建GUI的Python脚本中。

  1. 创建另一个名为callMultipleInheritance.pyw的Python文件并导入demoMultipleInheritance.py代码:

import sys
from PyQt5.QtWidgets import QDialog, QApplication
from demoMultipleInheritance 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:
    historyMarks = 0
    geographyMarks = 0
    def __init__(self, historyMarks, geographyMarks):
        self.historyMarks = historyMarks
        self.geographyMarks = geographyMarks
    def getHistoryMarks(self):
    	return self.historyMarks
    def getGeographyMarks(self):
        return self.geographyMarks
class Result(Student, Marks):
    totalMarks = 0
    percentage = 0
    def __init__(self, code, name, historyMarks,
        geographyMarks):
        Student.__init__(self, code, name)
        Marks.__init__(self, 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_())

它是如何工作的...

在这个代码中,你可以看到定义了一个名为Student的类。这个Student类包含两个类变量,分别为name和code,还有下面介绍的三个方法:

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

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

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

Marks类包含了两个类变量,分别为historyMarks和geographyMarks,还有下面的三个方法:

  • __init()__:这是一个构造函数,带有一个必需的self参数和另外两个historyMarks和geographyMarks参数。historyMarks和geographyMarks这两个参数将用于初始化historyMarks和geographyMarks类变量。

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

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

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

Result类包含两个类变量,分别是totalMarks和percentage,还有下面的三个方法:

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

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

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

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

在Student类构造函数中,学号和姓名分别赋给code和name类变量。类似的,在Marks类构造函数中,历史与地理分数分别赋给Marks类中的historyMarks和gepgraphyMarks这两个类变量。

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

在这之后,设置名为lineEditTotal的Line Edit部件以显示总分,也就是说,通过调用resultObj对象的getTotalMarks()方法获取历史与地理分数的和。此外,通过调用resultObj对象的getPercentage方法设置名为lineEditPercentage的Line Edit部件以显示分数和。

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