Ответ 1
Сначала рассмотрите свой последний вопрос, потому что он наиболее важен для структурирования проектов python. После того как вы разобрались, как правильно импортировать импорт в ваш проект, остальное становится намного легче справиться.
Главное, чтобы понять, что каталог текущего запуска script автоматически добавляется в начало sys.path
. Поэтому, если вы разместите main.py
script (то, что вы в настоящее время вызываете SailQt.pyw
) за пределами своего пакета в каталоге контейнеров верхнего уровня, это гарантирует, что импорт пакетов будет всегда работать независимо от того, где script выполняется из.
Таким образом, минимальная стартовая структура может выглядеть так:
project/
main.py
package/
__init__.py
app.py
mainwindow.py
Теперь, поскольку main.py
должен находиться за пределами каталога пакета python верхнего уровня, он должен содержать только минимальный код кода (достаточно для запуска программы). Учитывая указанную выше структуру, это будет означать не более того:
if __name__ == '__main__':
import sys
from package import app
sys.exit(app.run())
Модуль app
будет содержать большую часть фактического кода, необходимого для инициализации программы и настройки gui, который будет импортироваться следующим образом:
from package.mainwindow import MainWindow
и эта же форма полного описания импорта может использоваться из любого места с пакетом. Так, например, с этой несколько более сложной структурой:
project/
main.py
package/
__init__.py
app.py
mainwindow.py
utils.py
dialogs/
search.py
модуль search
может импортировать функцию из модуля utils
следующим образом:
from package.utils import myfunc
По конкретной проблеме доступа к строке __version__
: для программы PyQt вы можете поместить следующее в начало модуля app
:
QtGui.QApplication.setApplicationName('progname')
QtGui.QApplication.setApplicationVersion('0.1')
а затем позже введите имя/версию следующим образом:
name = QtGui.qApp.applicationName()
version = QtGui.qApp.applicationVersion()
Другие проблемы с вашей текущей структурой в основном связаны с сохранением разделения между файлами кода и файлами ресурсов.
Во-первых: дерево пакетов должно содержать только файлы кода (т.е. модули python). Файлы ресурсов относятся к директории проекта (то есть вне пакета). Во-вторых: файлы, содержащие код, сгенерированный из ресурсов (например, pyuic или pyrcc), вероятно, должны идти в отдельный подпакет (это также облегчает для вашего средства управления версиями исключение). Это приведет к созданию общей структуры проекта следующим образом:
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
Здесь Makefile
(или эквивалент) отвечает за создание файлов ui/rc, компиляцию модулей python, установку/удаление программы и т.д. Ресурсы, необходимые программе во время выполнения (например, файл базы данных), необходимо будет установить в стандартном местоположении, которое ваша программа знает, как найти (например, что-то вроде /usr/share/progname/database.db
в Linux). Во время установки Makefile
также необходимо сгенерировать исполняемый файл bash script (или эквивалент), который знает, где находится ваша программа и как ее запустить. То есть, что-то вроде:
#!/bin/sh
exec 'python' '/usr/share/progname/main.py' "[email protected]"
который, очевидно, должен быть установлен как /usr/bin/progname
(или что-то еще).
Вначале это может показаться довольно много, но, конечно, главное преимущество поиска структуры проекта, которая работает хорошо, заключается в том, что вы можете повторно использовать его для всех будущих проектов (и начать развивать свои собственные шаблоны и инструменты для настройки и управления этими проектами).