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_())