1

When a resource file is created via Qt Designer in a Form, the python code generated by the Qt Designer includes the following import statement:

import icons_rc

This import statement is same irrespective of the qrc file location (say shared location \Modules\ZA\RES\ or ui location \Modules\ZA\MDH).

The generated form works only if the generated python file for qrc file is in same location as form; else it raises the error:

  File "S:\...\Modules\ZA\MDH\ui_BObj.py", line 25, in <module>
      import icons_rc
  ModuleNotFoundError: No module named 'icons_rc'

This implies saving all images and compiled qrc file in same location as the UI/Form folder. I used PySide6 with pyside6-rcc and I believe this behaviour is same in PyQt as well.

Does this mean that qrc file for every UI form must be created in the respective locations, even if these forms use same common icon set?

All documentation/ posts on this topic talks about the qrc file format and compiler, but there is no indication on location of the resource files. Is it not possible to create a shared/ common icons qrc file in one location, compile it and then use it in different UI forms in different locations?

Ajay
  • 344
  • 3
  • 15
  • As [stated in the docs](https://doc.qt.io/qt-5/resources.html#resource-collection-files-op-op-qrc): "the listed resource files must be located in the same directory as the .qrc file, or one of its subdirectories". But you can easily work around this limitation with symlinks. – ekhumoro Mar 03 '23 at 13:22
  • I rechecked the same. I believe this is with reference to resource files (images etc. included in qrc) location relative to qrc file. The docs seems silent about the qrc file location in relation to generaed forms. Since generated import statement does not include any path, only work around seems commenting the generated import statement everytime and calling the resources' python file with desired path. This is working for a common resource file, but doesn't seem right approach. – Ajay Mar 03 '23 at 13:35
  • @Ajay Qt doesn't directly use the qrc files at runtime. As long as you're using the same qrc file, you can build it and move *that* in the same path of the generated python ui files or at least the path of the main script. PyQt's uic allows explicitly set the "package" name for resource imports, but it doesn't seem that PySide uic provides such feature. – musicamante Mar 03 '23 at 18:25
  • I still don't see why you can't just use a symlink to the common icons folder. But anyway, you are wrong to claim that the resources must be in the ui/form folder. I always put the designer/resource/qrc files in the top level folder of the project: i.e. *outside* of the python package tree (which only ever contains python modules). I then use the `--from-imports` option when generating the ui modules and put the compiled resource module alongside them. That allows sharing of resources, with or without symlinks. Thus, if the correct project structure is used, there should be no problems. – ekhumoro Mar 04 '23 at 01:33
  • @ekhumoro Thanks for the insight. Please help me with one more clarification: When you say '...when generating the ui modules and put the compiled resource module alongside them.', it means copying resource_rc.py in the same location as generated ui_FormXYZ.py file's folder, right? – Ajay Mar 04 '23 at 06:36
  • @Ajay The compiled ui modules are all in a sub-package within the main package tree, and the compiled resource modules go in that sub-package as well. I then have a [makefile](https://en.wikipedia.org/wiki/Make_(software)) at the top-level of the project that executes automatically whenever I run the program during development. This ensures any changes to the designer/resource/qrc files are immediately reflected in the compiled ui/resource modules. There's no *copying* of resource files as such: the makefile just calls `pyuic` and `pyrcc` with the relevant src/dest paths. – ekhumoro Mar 04 '23 at 14:11
  • @Ajay PS: see [this answer](https://stackoverflow.com/a/22183108/984421) for more details on the project structure I normally use. The most important thing is to get the python imports working correctly *first*, and then organise the rest of the project structure around that. – ekhumoro Mar 04 '23 at 14:17
  • @ekhumoro Your comments answers my question. Also, the details on project structure is useful. If you can put these comments together as answer, I'll be able to accept the answer. Thank you! – Ajay Mar 07 '23 at 04:47
  • @Ajay Glad you found it useful. I have now summarised the main points in an answer. – ekhumoro Mar 07 '23 at 15:08

1 Answers1

1

The resources files/qrc file do not need to be in the ui/form folder. If the right project structure is used, there should be no problems.

The designer/resource/qrc files can all go in the top level folder of the project: i.e. outside of the python package tree (which should only ever contain python modules). The --from-imports option should then be used when generating the ui modules, which can all go in a sub-package within the main python package tree, with the compiled resource modules going alongside them in the same sub-package. This will ensure the imports all work correctly - so long as the main.py script is located outside of the package, in the immediate parent folder.

Once the final project structure has been determined, a makefile (or equivalent) could also be added at the top-level of the project that will execute whenever the program is run during development. This makefile could have a target that calls pyuic and pyrcc with the relevant src/dest paths, which will ensure any changes to the designer/resource/qrc files are always immediately reflected in the compiled ui/resource modules.

A typical project structure might look something like this:

project/
    designer/
        mainwindow.ui
        dialog.ui
    icons/
        logo.png
    LICENSE
    Makefile
    main.py
    prog.sh
    resources.qrc
    run.sh
    package/
        __init__.py
        app.py
        mainwindow.py
        dialog.py
        ui/
            __init__.py
            mainwindow_ui.py
            dialog_ui.py
            resources_rc.py

(The prog.sh file is a simple shell script that starts the program, and is part of the main installation. The run.sh file is another shell script used only during development that - amongst other things - calls make before starting the program).

PS: for a more detailed look at project structure, see this answer.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336