Let's deal with your last question first, because it's the most important as far as structuring python projects is concerned. Once you've sorted out how to get the imports working correctly within your project, the rest becomes much easier to deal with.
The key thing to understand is that the directory of the currently running script is automatically added to the start of sys.path
. So if you put your main.py
script (what you're currently calling SailQt.pyw
) outside of your package in a top-level container directory, it will guarantee that package imports will always work, no matter where the script is executed from.
So a minimal starting structure might look like this:
project/
main.py
package/
__init__.py
app.py
mainwindow.py
Now, because main.py
must be outside of the top-level python package directory, it should contain only a minimal amout of code (just enough to get the program started). Given the above structure, that would mean not much more than this:
if __name__ == '__main__':
import sys
from package import app
sys.exit(app.run())
The app
module would contain most of the actual code necessary to initialize the program and set up the gui, which would be imported like this:
from package.mainwindow import MainWindow
and this same form of fully qualified import statement can be used from anywhere with the package. So, for example, with this slightly more complicated structure:
project/
main.py
package/
__init__.py
app.py
mainwindow.py
utils.py
dialogs/
search.py
the search
module could import a function from the utils
module like this:
from package.utils import myfunc
On the specific issue of accessing the __version__
string: for a PyQt program, you could put the following at the top of the app
module:
QtGui.QApplication.setApplicationName('progname')
QtGui.QApplication.setApplicationVersion('0.1')
and then access the name/version later like this:
name = QtGui.qApp.applicationName()
version = QtGui.qApp.applicationVersion()
The other issues with your current structure are mainly to do with maintaining separation between code files and resource files.
Firstly: the package tree should only contain code files (i.e. python modules). The resource files belong in the project directory (i.e. outside the package). Secondly: files containing code generated from resources (e.g. by pyuic or pyrcc) should probably go in a separate sub-package (this also makes it easy for your version control tool to exclude them). This would result in an overall project structure like this:
project/
db/
database.db
designer/
mainwindow.ui
icons/
logo.png
LICENSE
Makefile
resources.qrc
main.py
package/
__init__.py
app.py
mainwindow.py
ui/
__init__.py
mainwindow_ui.py
resources_rc.py
Here, the Makefile
(or equivalent) is responsible for generating the ui/rc files, compiling the python modules, installing/uninstalling the program, etc. Resources needed by the program at runtime (such as the database file), will need to be installed in a standard location that your program knows how to find (e.g. something like /usr/share/progname/database.db
on Linux). At installation-time, the Makefile
will also need to generate an executable bash script (or equivalent) that knows where your program is and how to start it. That is, something like:
#!/bin/sh
exec 'python' '/usr/share/progname/main.py' "$@"
which would obviously need to be installed as /usr/bin/progname
(or whatever).
This may seem like quite a lot to deal with at first, but of course the major benefit of finding a project structure that works well, is that you can re-use it for all future projects (and start to develop your own templates and tools for setting up and managing those projects).