Generally speaking, how are (Python) projects structured?

喜你入骨 提交于 2019-11-28 15:49:39

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).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!