Missing icons when running Notepad example on Raspberry Pi

Heads up! You've already completed this tutorial.

The notepad application example runs without problems on my Raspberry Pi. But the menu bar shows no icons, just blank rectangles. They do work if I click on them. What could be the problem?

If you've tried running the Notepad example on a Raspberry Pi and noticed that all the menu icons show up as blank rectangles, the buttons themselves still work — you just can't see the images. This is almost always caused by relative image paths not pointing where you expect them to.

When you use a relative path like os.path.join('images', 'my-icon.png'), Python resolves that path based on the current working directory — that is, the folder you were in when you launched the script. On a Raspberry Pi, this working directory can vary depending on how you start the application. If you double-click a .desktop shortcut, open it from a file manager, or run it from a different terminal directory, the working directory might not be the folder where your script lives. That means QIcon ends up looking for the images folder in the wrong place, finds nothing, and shows a blank rectangle instead.

Confirming the problem

You can verify this is what's happening by checking whether a QIcon actually loaded an image. In notepad.py, find the __init__ method:

python
def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

Add these lines right after:

python
icon = QIcon(os.path.join('images', 'blue-folder-open-document.png'))
print("availableSizes:", icon.availableSizes())

Run the application from a terminal and look at the output. If the icon loaded successfully, you'll see something like:

python
availableSizes: [PyQt5.QtCore.QSize(16, 16)]

If the list is empty:

python
availableSizes: []

that confirms QIcon couldn't find the file at the relative path.

Fixing the image paths

The most reliable fix is to build your image paths relative to the script file itself, rather than relying on the working directory. Python provides __file__, which always points to the location of the current script. You can use it to construct a stable base path.

At the top of your script (after your imports), add:

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

python
basedir = os.path.dirname(__file__)

This gives you the directory where notepad.py lives. Now, everywhere you create a QIcon with a relative path like this:

python
QIcon(os.path.join('images', 'blue-folder-open-document.png'))

Replace it with:

python
QIcon(os.path.join(basedir, 'images', 'blue-folder-open-document.png'))

Do this for every QIcon call in the file. The path will now always resolve correctly, no matter where you launch the script from.

Why this works

os.path.dirname(__file__) returns the absolute path to the folder containing your Python file. By joining this with the images subdirectory and the filename, you get a full, absolute path to each icon — something like /home/pi/notepad/images/blue-folder-open-document.png. This path doesn't depend on your terminal's current directory, so it works whether you run the script from the command line, a desktop shortcut, or a file manager.

A complete example

Here's what the relevant part of your script should look like after applying the fix:

python
import os
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMainWindow, QApplication

basedir = os.path.dirname(__file__)


class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        file_menu = self.menuBar().addMenu("&File")

        open_action = file_menu.addAction(
            QIcon(os.path.join(basedir, 'images', 'blue-folder-open-document.png')),
            "&Open"
        )
        save_action = file_menu.addAction(
            QIcon(os.path.join(basedir, 'images', 'disk.png')),
            "&Save"
        )

        # ... rest of your setup


app = QApplication([])
window = MainWindow()
window.show()
app.exec_()

With this change in place, your icons will display correctly on the Raspberry Pi — and on any other platform, regardless of how the application is started.

Over 15,000 developers have bought Create GUI Applications with Python & Qt!
Create GUI Applications with Python & Qt6
Get the book

Downloadable ebook (PDF, ePub) & Complete Source code

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

Missing icons when running Notepad example on Raspberry Pi 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.