How to Reference the App Context from a Window in fbs ApplicationContext

Passing the ApplicationContext to your MainWindow when using fbs for PyQt5 packaging
Heads up! You've already completed this tutorial.

When using fbs (fman build system) to package your PyQt5 applications, your main entry point is an ApplicationContext subclass. This context object is where you typically define helper methods -- like resource loaders -- and set up your main window. But what happens when your MainWindow needs to call a method on the ApplicationContext? For example, to load a resource image using get_resource()?

This creates a small chicken-and-egg situation: your MainWindow is created inside the ApplicationContext, but it also needs a reference back to the ApplicationContext. Fortunately, the solution is straightforward -- you just pass self when creating the window.

The Problem

Here's a typical fbs project structure where the issue shows up:

python
import sys
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtWidgets import QMainWindow


class MainWindow(QMainWindow):
    def __init__(self, ctx):
        super().__init__()
        self.ctx = ctx


class AppContext(ApplicationContext):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.window = MainWindow()  # Oops! Missing the context argument.

    def run(self):
        self.window.show()
        return self.app.exec_()

    def getImg(self):
        return self.get_resource('sample.png')


if __name__ == '__main__':
    appctxt = AppContext()
    sys.exit(appctxt.run())

The MainWindow.__init__ method expects a ctx parameter, but when the window is created inside AppContext.__init__, no argument is passed. Even if you fix that, you might wonder: how can I pass the AppContext to the window, when the AppContext hasn't finished initializing yet?

The Solution: Pass self

In Python, even though __init__ hasn't finished running, the object (self) already exists by the time __init__ is called. That means you can safely pass self to other objects during initialization. The AppContext instance is fully usable as a reference -- your MainWindow just stores it for later use.

Here's the fix:

python
self.window = MainWindow(self)  # Pass the AppContext instance to MainWindow

By passing self, your MainWindow now holds a reference to the AppContext, and can call any of its methods whenever it needs to.

Complete Working Example

Here's the full corrected code:

python
import sys
from fbs_runtime.application_context.PyQt5 import ApplicationContext
from PyQt5.QtWidgets import QMainWindow, QLabel, QVBoxLayout, QWidget


class MainWindow(QMainWindow):
    def __init__(self, ctx):
        super().__init__()
        self.ctx = ctx

        self.setWindowTitle("fbs App Context Example")

        layout = QVBoxLayout()

        # Use the context to access a resource.
        img_path = self.ctx.getImg()
        label = QLabel(f"Image path: {img_path}")
        layout.addWidget(label)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)


class AppContext(ApplicationContext):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.window = MainWindow(self)  # Pass self to give the window access to this context.

    def run(self):
        self.window.show()
        return self.app.exec_()

    def getImg(self):
        return self.get_resource('sample.png')


if __name__ == '__main__':
    appctxt = AppContext()
    sys.exit(appctxt.run())

Inside MainWindow, you can now call self.ctx.getImg() or any other method defined on your AppContext. This pattern works for any number of windows or widgets -- just pass the context through to whatever component needs it.

PyQt/PySide Development Services — Stuck in development hell? I'll help you get your project focused, finished and released. Benefit from years of practical experience releasing software with Python.

Find out More

Summary

When your MainWindow needs access to the ApplicationContext in an fbs project, pass self from the context when creating the window. Your window stores that reference and can use it freely to access resources, shared state, or any methods you've defined on the context. This cross-referencing pattern is common in Python and works perfectly well even during __init__.

Create GUI Applications with Python & Qt5 by Martin Fitzpatrick — (PyQt5 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!

More info Get the book

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

Packaging Python Applications with PyInstaller by Martin Fitzpatrick

This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.

More info Get the book

Martin Fitzpatrick

How to Reference the App Context from a Window in fbs ApplicationContext was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.