In this chapter, we will cover the following topics:
- Object-oriented programming
- Using classes in GUI
- Using single inheritance
- Using multilevel inheritance
- Using multiple inheritance
Object-oriented programming
Python supports object-oriented programming (OOP). OOP supports reusability; that is, code that was written earlier can be reused for making large applications, instead of starting from scratch. The term object in OOP refers to a variable or instance of a class, where a class is a template or blueprint of a structure that consists of methods and variables. The variables in the class are called data members, and the methods are called member functions. When instances or objects of a class are made, the objects automatically get access to data members and methods.
Creating a class
The class statement is used for creating a class. The following is the syntax for creating a class:
class class_name(base_classes):
statement(s)
Here, class_name is an identifier to identify the class. After the class statement comes the statements that make up the body of the class. The class body consists of different methods and variables to be defined in that class.
You can make an individual class or a class that inherits another class. The class that is being inherited is called the base class. The base_classes parameter after class_name in the syntax represents all the base classes that this class will be inheriting. If there is more than one base class, then they need to be separated by commas. The class that is being inherited is called the super class or base class, and the inheriting class is called a derived class or subclass. The derived class can use the methods and variables of the base class, and hence implements reusability:
class Student:
class Student:
name = ""
def __init__(self, name):
self.name = name
def printName(self):
return self.name
In this example, Student is a class that contains an attribute called name that is initialized to null.
Using the built-in class attributes
A class statement automatically assigns certain values to certain fixed class attributes. Those class attributes can be used to fetch information about the class. The list of class attributes are as follows:
- __name__: This attribute represents the class name used in the class statement
- __bases__: This attribute represents the base class names mentioned in the class statement
- __dict__: The dictionary object that represents other class attributes
- __module__: This attribute represents the module name in which the class is defined
A class can have any number of methods, and each method can have any number of parameters. One mandatory first parameter is always defined in a method, and that first parameter is usually named self (though you can give any name to this parameter). The self parameter refers to the instance of the class that calls the method. The syntax for defining methods in a class is as follows:
class class_name(base_classes):
Syntax:
variable(s)
def method 1(self):
statement(s)
[def method n(self):
statement(s)]
A class can have the following two types of data member:
- Class variable: These are the variables that are shareable by all instances, and changes made to these variables by any one instance can be seen by other instances too. These are the data members that are defined outside of any method of the class.
- Instance variable: These variables, which are defined inside a method, only belong to the current instance of the object and are known as instance variables. Changes made to instance variables by any instance are limited to that particular instance and don't affect the instance variables of other instances.
Let's see how to create an instance method and how it can be used to access class variables.
Accessing class variables in instance methods
To access class variables, the class variables must be prefixed with the class name. For example, to access the name class variable of the Student class, you need to access it as follows:
Student.name
You can see that the name class variable is prefixed with the Student class name.
Instances
To use the variables and methods of any class, we need to create its objects or instances. An instance of a class gets its own copy of variables and methods. This means the variable of one instance will not interfere with the variable of another instance. We can create as many instances of a class as desired. To create an instance of a class, you need to write the class name followed by arguments (if any). For example, the following statement creates an instance of the Student class with the name studentObj:
studentObj=Student()
You can create any number of instances of the Student class. For example, the following line creates another instance of the Student class:
courseStudent=Student()
Now, the instance can access the class attribute and method of the class.
You need to specify self explicitly when defining the method. While calling the method, self is not mandatory because Python adds it automatically.
To define the variables of a class, we get help from the __init__() method. The __init__() method is like a constructor in traditional OOP languages and is the first method to be executed after the creation of an instance. It is used for initializing the variables of the class. Depending on how the __init__() method is defined in the class, that is, with or without parameters, the arguments may or may not be passed to the __init__() method.
As mentioned earlier, the first argument of every class method is a class instance that is called self. In the __init__() method, self refers to the newly created instance:
class Student:
class Student:
name = ""
def __init__(self):
self.name = "David"
studentObj=Student()
In the preceding example, the studentObj instance is the instance of the Student class being created, and its class variable will be initialized to the David string.
Even arguments can be passed to the __init__() method, as shown in the following example:
class Student:
name = ""
def __init__(self, name):
self.name = name
studentObj=Student("David")
In the preceding example, the studentObj instance is created and the David string is passed to it. The string will be assigned to the name parameter defined in the __init__() method, which, in turn, will be used to initialize the class variable, name, of the instance. Remember, the __init__() method must not return a value.
Like the class variables, the methods of the class can be accessed by the instance of the class, followed by the method name, with a period (.) in between. Assuming there is a
printName() method in the Student class, it can be accessed via the studentObj instance with the following statement:
studentObj.printName()
Using classes in GUI
The data received from the user through the GUI can be directly processed by making use of simple variables, and the processed data can be displayed through variables only. But to keep the data in a structured format and get the benefits of OOP, we will learn to keep data in the form of classes. That is, the data accessed by the user through the GUI can be assigned to the class variables, processed, and displayed through class methods.
Let's create an application that will prompt the user to enter a name and, on clicking the push button after entering a name, the application will display a hello message along with the entered name. The name entered by the user will be assigned to a class variable and the hello message will also be generated by invoking the class method of the class.

How to do it...
The focus of this recipe is to understand how the data entered by the user is assigned to the class variable, and how the message displayed can be accessed via class methods. Let's create a new application based on the Dialog without Buttons template and follow these steps:
- Drag and drop two Label widgets, one Line Edit, and one Push Button widget onto the form.
- Set the text property of the first Label widget to Enter your name.
- Set the text property of the Push Button widget to Click.
- Set the objectName property of the Line Edit widget to lineEditName.
- Set the objectName property of the Label widget to labelResponse.
- Set the objectName property of the Push Button widget to ButtonClickMe.
- Save the application with the name LineEditClass.ui. The application will appear as shown in the following screenshot:
The user interface created with Qt Designer is stored in a .ui file, which is an XML file and needs to be converted to Python code. - To do the conversion, you need to open a Command Prompt window, navigate to the folder where the file is saved, and issue the following command line:
C:\Pythonbook\PyQt5>pyuic5 LineEdit.uiClass -o LineEditClass.py
The generated Python script, LineEditClass.py, can be seen in the source code bundle of this book.
- Treat the preceding code as a header file, and import it into the file from which you will invoke its user interface design.
- Create another Python file with the name callLineEditClass.pyw and import the LineEditClass.py code into it:
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_())
How it works...
In the LineEditClass.py file, a class with the name of the top-level object is created with
Ui_ prepended. That is, for the top-level object, Dialog, the Ui_Dialog class is created and stores the interface elements of our widget. That class has two methods, setupUi() and retranslateUi(). The setupUi() method creates the widgets that are used in defining the user interface in Qt Designer. Also, the properties of the widgets are set in this method. The setupUi() method takes a single argument, which is the top-level widget of the application, an instance of QDialog. The retranslateUi() method translates the interface.
In the callLineEditClass.py file, you can see that a class is defined called Student. The Student class includes a class variable called name and the following two methods:
- __init__(): It is a constructor that takes the mandatory self parameter and a name parameter, which will be used to initialize the name class variable
- printName: This method simply returns the value in the name class variable
The clicked()** event of the Push Button widget is connected to the dispmessage() method; after entering a name in the Line Edit widget, when the user clicks the push button, the dispmessage() method will be invoked. The dispmessage() method defines the object of the Student class by name, studentObj, and passes the name entered by the user in the Line Edit widget as a parameter. Hence, the constructor of the Student class will be invoked and the name entered by the user is passed to the constructor. The name entered in the Line Edit widget will be assigned to the class variable, name. After that, the Label widget called labelResponse is set to display the string, Hello, and the printName method of the Student class is invoked, which returns the string assigned to the name variable. Hence, on clicking the push button, the Label widget will be set to display the string, Hello, followed by the name entered by the user in the Line Edit box, as shown in the following screenshot:
Making the application more elaborate
We can also make use of two or more class attributes in the class.
Let's assume that besides the class name Student, we want to also add student's code to the class. In that case, we need to add one more attribute, code to the class, and also a getCode() method, which will access the student code assigned. Besides the class, the GUI will also change.
We need to add one more Label widgets and one Line Edit widget to the application and let's save it by another name, demoStudentClass. After adding the Label and Line Edit widgets, the user interface will appear as shown in the following screenshot:
The user interface file, demoStudentClass.ui, needs to be converted into Python code. The generated Python script, demoStudentClass.py, can be seen in the source code bundle of this book.
Let's create another Python file with the name callStudentClass.pyw and import the demoStudentClass.py code to it. The code in callStudentClass.pyw is as follows:

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_())
In the preceding code, you see that a class is defined called Student. The Student class includes the two class variables called name and code. Besides the two class variables, the Student class includes the following three methods too:
- __init__(): It is a constructor that takes the mandatory self parameter and two parameters, code and name, which will be used to initialize the two class variables, code and name
- getCode(): This method simply returns the value in the code class variable
- getName(): This method simply returns the value in the name class variable
The clicked() event of the Push Button widget is connected to the dispmessage() method; after entering the code and name in the Line Edit widget, when the user clicks the Push Button, the dispmessage() method will be invoked. The
dispmessage() method defines the object of the Student class by name, studentObj, and passes the code and name entered by the user in the Line Edit widgets as parameters. The constructor of the Student class, __init__(), will be invoked and the code and name entered by the user are passed to it. The code and name entered will be assigned to the class variables code and name, respectively. After that, the Label widget called labelResponse is set to display the code and name entered by invoking the two methods, getCode and getName, via the studentObj object of the Student class.
Hence, on clicking the push button, the Label widget will display the code and name entered by the user in two Line Edit widgets, as shown in the following screenshot:
Inheritance
Inheritance is a concept by which the method and variables of an existing class can be reused by another class, without the need for re-coding them. That is, existing code that is tested and run can be reused immediately in other classes.
Types of inheritance
The following are the three types of inheritance:
- Single inheritance: One class inherits another class
- Multilevel inheritance: One class inherits another class, which in turn is inherited by some other class
- Multiple inheritance: One class inherits two or more classes
Using single inheritance
Single inheritance is the simplest type of inheritance, where one class is derived from another single class, as shown in the following diagram:

Class B inherits class A. Here, class A will be called the super class or base class, and class B will be called the derived class or subclass.
The following statement defines single inheritance where the Marks class inherits the Student class:
class Marks(Student):
In the preceding statement, Student is the base class and Marks is the derived class. Consequently, the instance of the Marks class can access the methods and variables of the Student class.
Getting ready
To understand the concept of single inheritance through a running example, let's create an application that will prompt the user to enter the code, name, and history and geography marks of a student, and will display them on the click of a button.
The code and name entered by the user will be assigned to the class members of a class called Student. The history and geography marks will be assigned to the class members of another class called Marks. To access code and name, along with the history and geography marks, the Marks class will inherit the Student class. Using inheritance, the instance of the Marks class will access and display the code and name of the Student class.

How to do it...
Launch Qt Designer and create a new application based on the Dialog without Buttons template by performing the following steps:
- In the application, drag and drop five Label widgets, four Line Edit widgets, and one Push Button widget onto the form.
- Set the text property of the four Label widgets to Student Code, Student Name, History Marks, and Geography Marks.
- Delete the text property of the fifth Label widget, as its text property will be set through the code to display the code, name, and history and geography marks.
- Set the text property of the Push Button widget to Click.
- Set the objectName property of the four Line Edit widgets to lineEditCode, lineEditName, lineEditHistoryMarks, and lineEditGeographyMarks.
- Set the objectName property of the Label widget to labelResponse and the objectName property of the Push Button widget to ButtonClickMe.
- Save the application with the name demoSimpleInheritance.ui. The application will appear as shown in the following screenshot:
The user interface file, demoSimpleInheritance.ui, is an XML file and is converted into Python code using the pyuic5 utility. You can find the generated Python script, demoSimpleInheritance.py, in the source code bundle of this
book. The preceding code will be used as a header file, and will be imported in another Python script file, which will invoke the user interface design defined in, demoSimpleInheritance.py file.
- Create another Python file with the name callSimpleInheritance.pyw and import the demoSimpleInheritance.py code into it. The code in the Python script, callSimpleInheritance.pyw, is as given here:
import sys
from PyQt5.QtWidgets import QDialog, QApplication
from demoSimpleInheritance 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 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):
marksObj=Marks(self.ui.lineEditCode.text(), self.ui.lineEditName.text(), self.ui.lineEditHistoryMarks.text(), self.ui.lineEditGeographyMarks.text())
self.ui.labelResponse.setText("Code: "+marksObj.getCode()+", Name:"+marksObj.getName()+"\nHistory Marks:"+marksObj.getHistoryMarks()+", Geography Marks:"+marksObj.getGeographyMarks())
if __name__=="__main__":
app = QApplication(sys.argv)
w = MyForm()
w.show()
sys.exit(app.exec_())
How it works...
In this code, you see that a class is defined, called Student. The Student class includes two class variables called name and code, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and two parameters, code and name, that will be used to initialize the two class variables, code and name
- getCode(): This method simply returns the value in the code class variable
- getName(): This method simply returns the value in the name class variable
The Marks class inherits the Student class. Consequently, an instance of the Marks class will not only be able to access its own members, but also that of the Student class.
The Marks class includes two class variables called historyMarks and geographyMarks, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and four parameters, code, name, historyMarks, and geographyMarks. From this constructor, the constructor of the Student class will be invoked and the code and name parameters will be passed to this constructor. The historyMarks and geographyMarks parameters will be used to initialize the class members, historyMarks, and geographyMarks.
- getHistoryMarks(): This method simply returns the value in the historyMarks class variable.
- getGeographyMarks(): This method simply returns the value in the geographyMarks class variable.
The clicked()** event of the Push Button is connected to the dispmessage() method. After entering the code, name, and history and geography marks in the Line Edit widgets, when the user clicks the push button, the dispmessage() method will be invoked. The dispmessage() method defines the object of the Marks class by name, marksObj, and passes the code, name, and history and geography marks entered by the user in the Line Edit widgets as parameters. The constructor of the Marks class, __init__(), will be invoked and the code, name, history, and geography marks entered by the user are passed to it. From the constructor of the Marks class, the constructor of the Student class will be invoked and code and name will be passed to that constructor. The code and name parameters will be assigned to the code and name class variables, respectively, of the Student class. Similarly, the history and geography marks will be assigned
to historyMarks and geographyMarks class variables, respectively, of the Marks class. After that, the Label widget called labelResponse is set to display the code, name, and history and geography marks entered by invoking the four methods, getCode, getName, getHistoryMarks, and getGeographyMarks, via the marksObj object. The marksObj object of the Marks class gets the right to access the getCode and getName methods of the Student class because of using inheritance. Hence, on clicking the push button, the Label widget will display the code, name, history marks, and geography marks entered by the user via the Label widget called labelResponse, as shown in this screenshot:
Using multilevel inheritance
Multilevel inheritance is where one class inherits another single class. The inheriting class in turn is inherited by a third class, as shown in the following diagram:

In the preceding diagram, you can see that class B inherits class A and class C, in turn, inherits class B.
The following statement defines multilevel inheritance, where the Result class inherits the Marks class and the Marks class, in turn, inherits the Student class:
class Student:
class Marks(Student):
class Result(Marks):
In the preceding statement, Student is the base class and the Marks class inherits the Student class. The Result class inherits the Marks class. Consequently, the instance of the Result class can access the methods and variables of the Marks class, and the instance of the Marks class can access the methods and variables of the Student class.
Getting ready
To understand the concept of multilevel inheritance, let's create an application that will prompt the user to enter the code, name, history marks, and geography marks of a student and will display the total marks and percentage on the click of a button. The total marks will be the sum of history marks and geography marks. Assuming the maximum mark is 100, the formula for computing the percentage is: total marks/200 * 100.
The code and name entered by the user will be assigned to the class members of a class called Student. The history and geography marks will be assigned to the class members of another class called Marks. To access code and name along with the history and geography marks, the Marks class will inherit the Student class. Using this multilevel inheritance, the instance of the Marks class will access the code and name of the Student class. To calculate total marks and percentage, one more class is used, called the Result class. The Result class will inherit the Marks class. Consequently, the instance of the Result class can access the class members of the Marks class, as well as those of the Student class. The Result
class has two class members, totalMarks and percentage. The totalMarks class member will be assigned the sum of the historyMarks and geographyMarks members of the Marks class. The percentage member will be assigned the percentage acquired on the basis of the history and geography marks.

How to do it...
In all, there are three classes, named Student, Marks, and Result, where the Result class will inherit the Marks class and the Marks class, in turn, will inherit the Student class. Consequently, the members of the Result class can access the class members of the Marks class as well as those of the Student class. Here is the step-by-step procedure to create this application:
- Launch Qt Designer and create a new application based on the Dialog without Buttons template.
- Drag and drop six Label widgets, six Line Edit widgets, and one Push Button widget onto the form.
- Set the text property of the six Label widgets to Student Code, Student Name, History Marks, Geography Marks, Total, and Percentage.
- Set the text property of the Push Button widget to Click.
- Set the objectName property of the six Line Edit widgets to lineEditCode, lineEditName, lineEditHistoryMarks, lineEditGeographyMarks, lineEditTotal, and lineEditPercentage.
- Set the objectName property of the Push Button widget to ButtonClickMe.
- Disable the lineEditTotal and lineEditPercentage boxes by unchecking the Enable property from the Property Editor window. The lineEditTotal and lineEditPercentage widgets are disabled because values in these boxes will be assigned through the code and we don't want their values to be altered by the user.
- Save the application with the name demoMultilevelInheritance.ui. The application will appear as shown in the following screenshot:
The user interface file, demoMultilevelInheritance.ui, is an XML file and is converted into Python code by making use of the pyuic5 utility. You can see the generated Python script, demoMultilevelInheritance.py, in the source code bundle of this book. The demoMultilevelInheritance.py file will be used as a header file, and will be imported in another Python script file, which will use the GUI created in demoMultilevelInheritance.py.
- Create another Python file with the name callMultilevelInheritance.pyw and import the demoMultilevelInheritance.py code into it. The code in the Python script, callMultilevelInheritance.pyw, is as shown here:
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_())
How it works...
In the preceding code, in the callMultilevelInheritance.pyw file, you can see that a class is defined called Student. The Student class includes two class variables called name and code, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and two parameters, code, and name, that will be used to initialize the two class variables code and name
- getCode(): This method simply returns the value in the code class variable
- getName(): This method simply returns the value in the name class variable
The Marks class inherits the Student class. Consequently, an instance of the Marks class will not only be able to access its own members, but also those of the Student class.
The Marks class includes two class variables called historyMarks and geographyMarks, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and four parameters, code, name, historyMarks, and geographyMarks. From this constructor, the constructor of the Student class will be invoked and the code and name parameters will be passed to this constructor. The historyMarks and geographyMarks parameters will be used to initialize the historyMarks and geographyMarks class members.
- getHistoryMarks(): This method simply returns the value in the historyMarks class variable.
- getGeographyMarks(): This method simply returns the value in the geographyMarks class variable.
The Result class inherits the Marks class. An instance of the Result class will not only be able to access its own members, but also those of the Marks class and of the Student class too.
The Result class includes two class variables, called totalMarks and percentage, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and four parameters, code, name, historyMarks, and geographyMarks. From this constructor, the constructor of the Marks class will be invoked and the code, name, historyMarks, and geographyMarks parameters will be passed to that constructor. The sum of historyMarks and geographyMarks will be assigned to the totalMarks class variable. Assuming the maximum mark for each is 100, the percentage of the history and geography marks will be computed and assigned to the percentage class variable.
- getTotalMarks(): This method simply returns the sum of the historyMarks and geographyMarks class variables.
- getPercentage(): This method simply returns the percentage of the history and geography marks.
The clicked() event of the Push Button widget is connected to the dispmessage() method. After entering code, name, history marks, and geography marks in the Line Edit widgets, when the user clicks the push button, the dispmessage() method will be invoked. The dispmessage() method defines the object of the Result class by name, resultObj, and passes the code, name, history, and geography marks entered by the user in the Line Edit widgets as parameters. The constructor of the Result class, __init__(), will be invoked and the code, name, history marks, and geography marks entered by the user are passed to it. From the Result class's constructor, the Marks class's constructor will be invoked and code, name, history marks, and geography marks will be passed to that constructor. From the Marks class's constructor, the Student class constructor will be invoked and the code and name parameters are passed to it. In the Student class's constructor, the code and name parameters will be assigned to the class variables code and name, respectively. Similarly, the history and geography marks will be assigned to the historyMarks and geographyMarks class variables, respectively, of the Marks class.
The sum of historyMarks and geographyMarks will be assigned to the totalMarks class variable. Also, the percentage of the history and geography marks will be computed and assigned to the percentage class variable.
After that, the Line Edit widget called lineEditTotal is set to display the total marks, that is, the sum of history and geography marks, by invoking the getTotalMarks method via resultObj. Also, the Line Edit widget called lineEditPercentage is set to display the percentage of marks by invoking the getPercentage method via resultObj.
Hence, on clicking the push button, the Line Edit widgets called lineEditTotal and lineEditPercentage will display the total marks and percentage of history and geography marks entered by the user, as shown in the following screenshot:
Using multiple inheritance
Multiple inheritance is where one class inherits two or more classes, as shown in the following diagram:

Class C inherits both classes, class A and class B.
The following statement defines multilevel inheritance where the Result class inherits the Marks class and the Marks class in turn inherits the Student class:
class Student:
class Marks:
class Result(Student, Marks):
In the preceding statements, Student and Marks are the base classes and the Result class inherits both the Student class and the Marks class. Consequently, the instance of the Result class can access the methods and variables of the Marks and Student classes.
Getting ready
To understand the concept of multilevel inheritance practically, let's create an application that will prompt the user to enter the code, name, history marks, and geography marks of a student, and will display the total marks and percentage on the click of a button. The total marks will be the sum of history marks and geography marks. Assuming the maximum mark for each is 100, the formula for computing the percentage is: total marks/200 * 100.
The code and name entered by the user will be assigned to the class members of a class called Student. The history and geography marks will be assigned to the class members of another class called Marks.
To access code and name, along with the history and geography marks, the Result class will inherit both classes, the Student class as well as the Marks class. Using this multiple inheritance, the instance of the Result class can access the code and name of the Student class, as well as the historyMarks and geographyMarks class variables of the Marks
class. In other words, using multiple inheritance, the instance of the Result class can access the class members of the Marks class, as well as those of the Student class. The Result class has two class members, totalMarks and percentage. The totalMarks class member will be assigned the sum of the historyMarks and geographyMarks members of the Marks class. The percentage member will be assigned the percentage acquired on the basis of the history and geography marks.

How to do it...
Let's understand through a step-by-step procedure how multilevel inheritance is applied to three classes, Student, Marks, and Result. The Result class will inherit both classes, Student and Marks. These steps explain how the members of the Result class can access the class members of the Student and Marks classes through multilevel inheritance:
- Launch Qt Designer and create a new application based on the Dialog without Buttons template.
- In the application, drag and drop six Label widgets, six Line Edit widgets, and one Push Button widget onto the form.
- Set the text property of the six Label widgets to Student Code, Student Name, History Marks, Geography Marks, Total, and Percentage.
- Set the text property of the Push Button widget to Click.
- Set the objectName property of the six Line Edit widgets to lineEditCode, lineEditName, lineEditHistoryMarks, lineEditGeographyMarks, lineEditTotal, and lineEditPercentage.
- Set the objectName property of the Push Button widget to ButtonClickMe.
- Disable the lineEditTotal and lineEditPercentage boxes by unchecking the Enable property from the Property Editor window. The lineEditTotal and lineEditPercentage boxes are disabled because values in these boxes will be assigned through the code, and we don't want their values to be altered by the user.
- Save the application with the name demoMultipleInheritance.ui. The application will appear as shown in the following screenshot:
The user interface file demoMultipleInheritance .ui is an XML file and is converted into Python code using the pyuic5 utility. You can find the generated Python code, demoMultipleInheritance.py, in the source code bundle of this book. The demoMultipleInheritance.py file will be used as a header file and will be imported in another Python script file, which will invoke the GUI created in the demoMultipleInheritance.py file.
- Create another Python file with the name callMultipleInheritance.pyw and import the demoMultipleInheritance.py code into it:
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_())
How it works...
In this code, you can see that a class is defined called Student. The Student class includes two class variables called name and code, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and two parameters, code and name, that will be used to initialize the two class variables code and name
- getCode(): This method simply returns the value in the code class variable
- getName(): This method simply returns the value in the name class variable
The Marks class includes two class variables, called historyMarks and geographyMarks, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and two parameters, historyMarks and geographyMarks. The historyMarks and geographyMarks parameters will be used to initialize the historyMarks and geographyMarks class members.
- getHistoryMarks(): This method simply returns the value in the historyMarks class variable.
- getGeographyMarks(): This method simply returns the value in the geographyMarks class variable.
The Result class inherits the Student class as well as the Marks class. An instance of the Result class will not only be able to access its own members, but also those of the Marks class and of the Student class too.
The Result class includes two class variables called totalMarks and percentage, along with the following three methods:
- __init__(): It is a constructor that takes the mandatory self parameter and four parameters, code, name, historyMarks, and geographyMarks. From this constructor, the Student class constructor will be invoked and the code and name parameters will be passed to that constructor. Also, from this constructor, the Marks class constructor will be invoked and the historyMarks and geographyMarks parameters will be passed to that constructor. The sum of historyMarks and geographyMarks will be assigned to the totalMarks class variable. Assuming the maximum mark for each is 100, the percentage of the history and geography marks will be computed and assigned to the percentage class variable.
- getTotalMarks(): This method simply returns the sum of the historyMarks and geography class variables.
- getPercentage(): This method simply returns the percentage of history and geography marks.
The clicked()** event of the Push Button widget is connected to the dispmessage() method. After entering code, name, history marks, and geography marks in the Line Edit widgets, when the user clicks the push button, the dispmessage() method will be invoked. The dispmessage() method defines the object of the Result class by name, resultObj, and passes the code, name, history marks, and geography marks entered by the user in the Line Edit widgets as parameters. The constructor of the Result class, __init__(), will be invoked and the code, name, history marks, and geography marks entered by the user are passed to it. From the Result class's constructor, the Student class constructor and the Marks class constructor will be invoked. The code and name will be passed to the Student class constructor, and history and geography marks will be passed to the Marks class constructor.
In the Student class constructor, the code and name will be assigned to the code and name class variables, respectively. Similarly, in the Marks class constructor, the history and geography marks will be assigned to the historyMarks and geographyMarks class variables, respectively, of the Marks class.
The sum of historyMarks and geographyMarks will be assigned to the totalMarks class variable. Also, the percentage of the history and geography marks will be computed and assigned to the percentage class variable.
After that, the Line Edit widget called lineEditTotal is set to display the total marks, that is, the sum of the history and geography marks, by invoking the
getTotalMarks method via resultObj. Also, the Line Edit widget called lineEditPercentage is set to display the percentage of marks by invoking the getPercentage method via resultObj.
Hence, on clicking the push button, the Line Edit widgets called lineEditTotal and lineEditPercentage will display the total marks and percentage of the history and geography marks entered by the user, as shown in the following screenshot:
'Qt5 Python GUI Programming Cookbook' 카테고리의 다른 글
Networking and Managing Large Documents (1) | 2023.02.28 |
---|---|
Understanding Dialogs (0) | 2023.02.28 |
Working with Date and Time (0) | 2023.02.28 |
Event Handling - Signals andSlots (0) | 2023.02.27 |
Creating a User Interface with Qt Components (0) | 2023.02.27 |
댓글