Use of instance attribute inherited from parent class

1

I have the following code:

from PyQt5.QtWidgets import QMainWindow,QApplication
from PyQt5 import uic


class Primera(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        uic.loadUi("Inicio.ui",self)
        self.preview_alta #QpushButton

class image_anadir(Primera):
    def __init__(self):
        pr = Primera()
        pr.preview_alta.clicked.connect(lambda:print("add"))

app = QApplication([])
p = Primera()
p.show()
app.exec_()

Inside the class Primera that inherits from QMainWindow I have a button self.preview_alta , but I need to occupy that button in class image_anadir .

However, it does not execute the action that I indicate within the class image_anadir .

What was wrong?

    
asked by Mystic_Force 01.08.2018 в 05:52
source

1 answer

1

I think you have some confusion with the paradigm and concepts of the OOP, basically you have two problems:

  • In no instances the class image_añadir , you only create an object of Primera ( p = Primera ), so to start nothing of what you do in image_añadir is going to be seen anywhere because not the instances. Keep in mind that a class by itself is just a scheme or template that is used to create objects and that the inheritance only works in one direction, the daughter class inherits the characteristics of the class (or classes) father but never the other way around .

  • When creating your class image_añadir you are between an inheritance attempt and a composition attempt without completing either, if you are going to use inheritance, do not instancies the parent class inside of the daughter class initializer.

    The image_añadir class when inheriting from Primera gets its methods and attributes including __init__ and preview_alta .

    Now, in your daughter class you overwrite the initializer ( __init__) inherited from the parent , to make use of the attributes defined in the initializer of the upper class you have to explicitly call it in the derived class initializer , this will allow all the tasks necessary to correctly initialize the instance to be carried out and all the attributes defined in the initializer of the parent class to be initialized correctly and become available in the derivative class (like the load of the .ui, without which the attribute preview_alta will not exist.) It is exactly the same as you have done in Primera with QMainWindow.__init__(self) , with this you can use your inherited button as you would in Primera :

    self.preview_alta.clicked.connect(lambda:print("add")) :

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import uic



class Primera(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("Inicio.ui", self)


class ImageAnadir(Primera):
    def __init__(self):
        super().__init__()  # Primera.__init__(self)
        self.preview_alta.clicked.connect(lambda: print("add"))


app = QApplication(sys.argv)
w = ImageAnadir()           # Instancia de la subclase.
w.show()
sys.exit(app.exec_())

super allows you to refer to the parent class and call the method __init__ of it as it does Primera.__init__(self) , it has special utility in cases of multiple inheritance. For more information it may be useful:

What is and what utility does super have in POO?

As a recommendation, consider naming classes beginning with a capital letter and using CamelCase as recommended in PEP 8 - Style Guide for Python Code , this differentiates the methods / functions and variables classes.

Edit:

Regarding the comment, whether or not the class is defined in another module does not matter in terms of using inheritance or composition. Imagine that Principal is defined in a module called interfaz.py , assuming it is in the same directory as the script where we define ImageAnadir , just import the class with:

from interfaz import Principal

to be able to use it.

As for an example of composition, the rough composition means that our class instantiates other classes and manages these objects to implement the desired functionalities.

Using inheritance or composition (or aggregation ...) will depend on our specific case. Imagine that we have the class Mamifero and class Gato , the logical thing is that Gato inherit Mamífero because a cat is a mammal (and always will be). If we have a class Barco and a class Vela the logical thing is to use composition because a boat has a sail that it uses to navigate, it is not a sail, it is more, a boat may not have a sail and remain a ship. Yes, they are very clear examples and in reality the limits are not always clear, but those two verbs ( be and have ) are very helpful.

Since I have no idea what you're trying to do, I'm just going to leave a very simple example of composition with your classes, which I do not know if they will really make any sense given the lack of context:

import sys
from PyQt5.QtWidgets import  QApplication
from interfaz import Primera



class ImageAnadir:                 # No hereda de Principal
    def __init__(self): 
        self._interfaz = Primera() # Instancia un objeto de la clase Principal
        self._interfaz.preview_alta.clicked.connect(self.obtener_imagen)

    def obtener_imagen(self):
        print("Imágen obtenida...")

    def abrir_ventana(self):
        self._interfaz.show()


app = QApplication(sys.argv)
im = ImageAnadir()
im.abrir_ventana()
sys.exit(app.exec_())
    
answered by 01.08.2018 / 09:50
source