Reputation: 2146
I'm in the process of structuring my PyQt5 application to more established conventions. Now it looks like this
MyProj
├── my_qt_tool
│ ├── __init__.py
│ ├── class1.py
│ ├── my_qt_tool.py
│ ├── wizard1.py
│ ├── resources
│ │ └── templates
│ │ └── tool.conf.template
│ └── ui
│ ├── __init__.py
│ ├── mainwindow.py
│ ├── mainwindow.ui
│ ├── wizard_01_start.py
│ ├── wizard_01_start.ui
│ ├── ...
├── my_qt_tool.spec # for PyInstaller
├── bin
│ └── generate_ui_code.py # for compiling Qt *.ui to *.py
├── dist
│ └── my_qt_tool
├── environment.yml # conda environment requirements.
├── LICENSE
└── README.md
So MyProj
is the top-level git repo, my_qt_tool
is the package of my application, with a subpackage for UI specific code, my_qt_tool.py
contains the "main" code which runs the GUI, class1.py
handles business logic and wizard1.py
is just some extra class for a GUI wizard.
Q1: Is this project structure canonical? Is the main function where it should be? Should *.ui files be separated to resources
?
Now, after some haggling with imports, I added my_qt_tool
as source directory to pycharm to make the imports work and created a run for my_qt_tool.py
with working dir MyProj/my_qt_tool
.
Q2: Technically, I want the working dir to be MyProj
, but then I would have to reference resources/templates/tool.conf.template
with my_qt_tool/resources..
, which seems yucky... or is this the way to do it?
Now the imports in my_qt_tool
look like this:
from class1 import DataModel
from ui.mainwindow import Ui_MainWindow
...
so no relative imports or the like, because everything is in the same package, right? (Again: to make this work, I had to add my_qt_tool
as source directory in my PyCharm project settings...)
Q3: Okay, now the thing that doesn't work. Running PyInstaller on the spec file, which is pretty much stock with Analysis(['my_qt_tool/my_qt_tool.py'], ...
, the resulting binary fails to start with the error message: ModuleNotFoundError: No Module named 'class1'
. How can I fix this up?
Upvotes: 1
Views: 2007
Reputation: 1052
Q1
if project going to get larger you may create module specific folders and each module has py and gui files within. structure it as mvc project folders. For folder structure of mvc: https://www.tutorialsteacher.com/mvc/mvc-folder-structure and here is hov model-view architecture can be implemented https://www.learnpyqt.com/courses/model-views/modelview-architecture/.
Q2
read resources/templates/tool.conf.template when application bootstrapped instead of statically referencing. this could be done in generate_ui_code.py to load all configs as part of app reference
so no relative imports or the like, because everything is in the same package, right? (Again: to make this work, I had to add my_qt_tool as source directory in my PyCharm project settings...)
no need to add my_qt_tool if bootstrapped properly
Q3
add these 2 lines top of spec file
import sys
sys.setrecursionlimit(5000)
if you still encounter class1 related issue try importing it in where pyinstaller being called for your case its my_qt_tool.py
fix pyinstaller issue first and than consider refactoring folder structure with model-view conventions.
here are some fairly large project examples
Upvotes: 1