Search code examples
pythonpyqtqmainwindowqapplication

Accessing a common data object in a PyQt application


I have a GUI programmed in PyQt with many widgets and different windows, etc. The data for the GUI is stored in a python object. This object should be reachable from every widget in the program. Where should I put this object?

Right now I have it in the QMainWindow instance that is used for the program's main window. The problem is that it is hard to reach the QMainWindow object from deeply nested widgets. It seems much simpler to use the QApplication instance for that, because you can get it with QtCore.QCoreApplication.instance() (as shown in this answer). However, I couldn't find any other examples encouraging you to change the QApplication class, so I wonder if it really should be used that way.

What approach would you suggest?


Solution

  • The correct approach is to put this data/settings object in a separate module. This can then be simply imported wherever it is needed. Ideally, the module (and the code which creates the data/settings object) should be largely independent from the rest of the application.

    There is no real value in tying the data/settings object to the application instance, since you would still have to import either QApplication or qApp to access it anyway. And the same thing applies to the QMainWindow - it just moves the problem to a different location, and adds an unnecessary layer of indirection. Another big problem with this approach is that the data/settings object cannot be accessed until an instance of the application or main window becomes available. Very often, the data/settings object will be required during the initialisation of various parts of the application, so tying it to specific GUI elements can easily lead to circular dependencies, or other ordering problems.

    I suppose the key design principle here is Loose Coupling: once you've decoupled your data/settings object from the GUI, the rest of the application can access it wherever and whenever it is required.