Matthew
Matthew

Reputation: 433

Calling function in parent class and accessing parent self

In my main window I set a variable self.print_this. I then call another class PhotoViewer and then in that class I call a function from my main window. In that function I try to print the self.print_this but I get the following error: AttributeError: PhotoViewer object has no attribute print_this How do I access the self of the window class or avoid sending the self of PhotoViewer to the printfromwindow function?

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QPoint, QRect, QSize, pyqtSignal
from PyQt5.QtWidgets import QMainWindow, QApplication, QRubberBand, QColorDialog
from PyQt5.QtGui import QPixmap, QPainter, QPen
import sys

class PhotoViewer(QtWidgets.QGraphicsView):
    photoClicked = QtCore.pyqtSignal(QtCore.QPoint)
    rectChanged = pyqtSignal(QRect)

    def __init__(self, parent):
        super(PhotoViewer, self).__init__(parent)
        Window.printfromwindow(self)

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.print_this='test'
        PhotoViewer(self)

    def printfromwindow(self):
        print(self.print_this)

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 800, 600)
    window.show()
    sys.exit(app.exec_())

Upvotes: 0

Views: 780

Answers (2)

David Zemens
David Zemens

Reputation: 53623

Untested, but perhaps something like this. Note that in your code, you're calling methods of the Window and PhotoViewer classes but not constructing an instance of those classes.

  1. You need to instantiate and retain those instances within their parent/child class instances, if you want to be able to reference their methods/properties.

  2. As noted in my comment above, Window.printfromwindow(self) should not have the self argument (and should instead refer to <instance of Window>.printfromwindow().

In the Window constructor, I assign self.viewer an instance of the PhotoViewer class and pass self (which is a Window instance) as the parent argument to its constructor.

Then, in PhotoViewer class constructor, we do self.window = parent which should allow you to call self.window.printfromwindow():

class PhotoViewer(QtWidgets.QGraphicsView):
    photoClicked = QtCore.pyqtSignal(QtCore.QPoint)
    rectChanged = pyqtSignal(QRect)

    def __init__(self, parent):
        super(PhotoViewer, self).__init__(parent)
        self.window = parent  # relates the "parent" Window instance to this "child" PhotoViewer instance
        self.window.printfromwindow()  # calls the printfromwindow method from the "parent" Window instance

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.print_this='test'
        self.viewer = PhotoViewer(self)  # creates an instance of PhotoViewer class as an attribute of this Window instance

    def printfromwindow(self):
        print(self.print_this)

If you want to make this more readily available (i.e., not just from within the constructor of PhotoViewer) then assign the Window.printfromwindow to an attribute of the PhotoViewer, like:

class PhotoViewer(QtWidgets.QGraphicsView):
    photoClicked = QtCore.pyqtSignal(QtCore.QPoint)
    rectChanged = pyqtSignal(QRect)

    def __init__(self, parent):
        super(PhotoViewer, self).__init__(parent)
        self.window = parent  # relates the "parent" Window instance to this "child" PhotoViewer instance
        self.printfromwindow = self.window.printfromwindow  

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.print_this='test'
        self.viewer = PhotoViewer(self)  # creates an instance of PhotoViewer class as an attribute of this Window instance

    def printfromwindow(self):
        print(self.print_this)

Since functions are first-level objects in python, you can do this:

app = QtWidgets.QApplication(sys.argv)
window = Window()
window.viewer.printfromwindow()

Upvotes: 1

Barb
Barb

Reputation: 437

To access a parent class you need to pass the parent class through the function. def printfromwindow(Window). Then you inherit all of the attributes from the parent class. You can also modify a subclass with super().__init__ to add changes to the sub classes without effecting the parent class

Upvotes: 0

Related Questions