drewd423
drewd423

Reputation: 351

In PyQT how to open a child window that has access to the parent's attributes?

I have an engine module that contains several helper methods and attributes:

engine.py

class World:
    def __init__(self):
        # stuff

    def foo(a, b):
        c = a + b # trivial example
        return c

Then I have a main.py which incorporates the UI files (created in QtDesigner and converted to .py using a script I have):

main.py

from PyQt4 import QtGui
import design1
import design2
import engine

class MainWindow(QtGui.QMainWindow, design1.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.world = engine.World()

        self.new_window_button.clicked.connect(self.open_new_window)

    def open_new_window(self):
        self.window_to_open = ChildWindow(self)
        self.window_to_open.show()

class ChildWindow(QtGui.QMainWindow, design2.Ui_MainWindow):
    def __init__(self, parent):
        super(ChildWindow, self).__init__(parent)
        self.setupUi(self)
        print(self.world.foo(1, 2)) # trivial example

def main():
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()

If I take out the print line, ChildWindow opens fine. But with it in I get the error:

AttributeError: 'ChildWindow' object has no attribute 'world'

I know I'm doing something silly but I can't figure it out.

edited main.py

from PyQt4 import QtGui
import design1
import design2
import engine

class MainWindow(QtGui.QMainWindow, design1.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.world = engine.World()

        self.new_window_button.clicked.connect(self.open_new_window)

    def open_new_window(self):
        self.window_to_open = ChildWindow(self)
        self.window_to_open.show()

class ChildWindow(QtGui.QMainWindow, design2.Ui_MainWindow):
    def __init__(self, parent):
        super(ChildWindow, self).__init__(parent)
        self.setupUi(self)
        print(self.parent().world.foo(1, 2)) # trivial example

def main():
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()

I now get the error:

TypeError: foo() takes 2 positional arguments but 3 were given

Upvotes: 5

Views: 5262

Answers (1)

eyllanesc
eyllanesc

Reputation: 243973

The ChildWindow class does not have the attribute to world, but you can access it through the parent() function, which returns the parent since you have used the following statement: self.window_to_open = ChildWindow (self)

You must change

self.world.foo(1, 2)

to

self.parent().world.foo(1, 2)

Your method must be declared as static since it does not use self as a parameter.

class World:
    def __init__(self):
        # stuff

    @staticmethod
    def foo(a, b):
        c = a + b # trivial example
        return c

or

def foo(self, a, b):
    c = a + b # trivial example
    return c

Upvotes: 2

Related Questions