Search code examples
pythonqtpyside6

Project structure design: where store toolbar icons and how access them


I am working on a GUI project that will contain a set of icon images. I instinctively created an img directory in the root project directory.

I was planning on using the root class of my application as a place to store stuff like this, and gather the QIcon objects in a dictionary

self.toolbarIcons = {QIcon("<path-to-image.png>")}

Then the question is how to best access these icons from several classes down the hierarchy. When I was using tkinter the structure was very linear as each widget was a child of its parent.

The way I have set up the Qt application (using PySide6), the base class is QApplication. In here I construct a QMainWindow, in which I set the various widgets (central widget, toolbars, statusbar, etc.).

What is a good strategy that scales well as the application complexity grows? Should I store icons relevant for a particular widget as class attributes to that particular class (and therefore spreading the icon objects throughout the code)? I like the idea of keeping the icon objects together in one spot.

I have the code separated in different directories, but basically the structure is this (MWE):

from PySide6.QtWidgets import QApplication, QMainWindow, QTableWidget, QToolBar
from PySide6.QtGui import QIcon


class MyApplication(QApplication):
    def __init__(self, *args, **kwargs):
        QApplication.__init__(self, *args, **kwargs)
        
        self.icons = {'do_stuff': QIcon('<path-to-icon.png>')}
        self.mainwindow = MyMainWindow()
        self.mainwindow.show()


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

        self.setCentralWidget(MyCentralWidget(self))
        self.addToolBar(MyToolBar(self))


class MyCentralWidget(QTableWidget):
    def __init__(self, parent, *args, **kwargs):
        QTableWidget.__init__(self, parent, *args, **kwargs)
        self.parent = parent


class MyToolBar(QToolBar):
    def __init__(self, parent, *args, **kwargs):
        QToolBar.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        # How to access MyApplication.icons['do_stuff'] from here?


if __name__ == '__main__':
    app = MyApplication()
    app.exec_()



Solution

  • The most trivial solution is that QApplication is a singleton that can be accessed in any method using the instance() method:

    icon = MyApplication.instance().icons["do_stuff"]
    

    But I don't recommend it since a better option is to create a settings file where those properties are defined and import it:

    settings.py

    ICONS = {"do_stuff": "<path-to-icon.png>"}
    

    then

    *.py

    from settings import ICONS
    
    # ...
    
    icon = QIcon(ICONS["do_stuff"])