Fixing "No such file or directory" for .ui Files When Using fbs freeze

Why your .ui file works with fbs run but breaks after freezing, and how to fix it
Heads up! You've already completed this tutorial.

I created a UI using Qt Designer and placed it in src/main/resources/base/mainwindow.ui. Everything works with fbs run, but when I use fbs freeze and try to run the frozen app, I get a FileNotFoundError: [Errno 2] No such file or directory: 'mainwindow.ui'. How do I fix this?

When you're developing a PyQt5 application with fbs and loading .ui files at runtime, you'll often find that everything works perfectly during development (fbs run) but falls apart as soon as you freeze the application. The error looks something like this:

python
FileNotFoundError: [Errno 2] No such file or directory: 'mainwindow.ui'
[61742] Failed to execute script main

This is a common stumbling block, and the cause is straightforward once you understand how file paths change when an application is frozen.

Why This Happens

When you load your .ui file with a relative path like this:

python
qtCreatorFile = "mainwindow.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

Python resolves that relative path based on the current working directory — the folder from which the program is executed. During development, fbs run sets things up so that your working directory matches your project structure, and the file is found without trouble.

But after freezing, the frozen executable lives in a different location (target/), and the working directory when a user launches it could be almost anything. The relative path "mainwindow.ui" no longer points to the right place, and Python can't find the file.

The Fix: Use the fbs Application Context

The fbs framework provides a built-in way to locate resource files regardless of whether you're running in development or from a frozen build. That's what ApplicationContext.get_resource() is for.

If your .ui file is located at:

python
src/main/resources/base/mainwindow.ui

Then you can get the correct absolute path to it like this:

python
from fbs_runtime.application_context import ApplicationContext

appctxt = ApplicationContext()
ui_path = appctxt.get_resource("mainwindow.ui")

The get_resource() method returns the full, absolute path to the file — whether you're running with fbs run or from a frozen executable. This is the recommended approach when using fbs.

Here's a complete working example:

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


class AppContext(ApplicationContext):
    def run(self):
        ui_path = self.get_resource("mainwindow.ui")
        Ui_MainWindow, QtBaseClass = uic.loadUiType(ui_path)

        class MainWindow(QMainWindow, Ui_MainWindow):
            def __init__(self):
                super().__init__()
                self.setupUi(self)

        self.window = MainWindow()
        self.window.show()
        return self.app.exec_()


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

Notice that uic.loadUiType() is called inside the run() method, after the application context is available. This ensures the resource path is resolved correctly before the .ui file is loaded.

An Alternative: Build an Absolute Path Yourself

If for some reason you don't want to use the application context to locate the file, you can construct an absolute path manually using sys.argv[0]. This points to the script (or frozen executable) that was launched, so you can use it to find files that sit alongside it:

python
import os
import sys
from PyQt5 import uic

qtCreatorFile = os.path.join(
    os.path.abspath(os.path.dirname(sys.argv[0])),
    "mainwindow.ui"
)
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

This builds a full path by combining the directory of the running script with the filename. It works in both development and frozen environments, as long as the .ui file ends up in the same folder as the executable after freezing.

That said, using get_resource() is still the better option with fbs, because fbs already handles the details of where resource files end up during freezing. You don't have to think about it.

A Note on the Original Code

The original code also had this block:

python
if __name__ == '__main__':
    appctxt = AppContext()
    stylesheet = appctxt.get_resource('mainwindow.ui')
    appctxt.app.setStyleSheet(open(stylesheet).read())
    exit_code = appctxt.run()
    sys.exit(exit_code)

Here, get_resource('mainwindow.ui') is being used to load the .ui file as a stylesheet, which isn't correct. A .ui file is an XML file that describes widget layout — it's not a Qt stylesheet (.qss). Loading it with setStyleSheet() won't produce an error, but it also won't do anything useful. If you have a separate .qss stylesheet, load that with setStyleSheet(). Load the .ui file with uic.loadUiType() as shown above.

Summary

When packaging a PyQt5 app with fbs, any file you reference at runtime needs to be located using an absolute path. Relative paths work during development but fail after freezing because the working directory changes.

The simplest and most reliable fix is to use appctxt.get_resource("mainwindow.ui") to get the full path to your .ui file, and then pass that path to uic.loadUiType(). This works consistently in both development and production.

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

Create GUI Applications with Python & Qt6 by Martin Fitzpatrick

(PyQt6 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!

More info Get the book

Martin Fitzpatrick

Fixing "No such file or directory" for .ui Files When Using fbs freeze 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.