Pull to refresh

Пример разработки небольшого python+PyQt4 приложения для учетной системы

Reading time4 min
Views15K
Часто приходится разрабатывать приложения для корпоративной системы которые должны были функционировать еще вчера, не требующие строго соответствия корпоративным стандартам. Такими приложениями могут представлять cms к сайтам, gui для сервисов под *nix системы просто приложением учетной системы. Разработка приложений подобного рода на скриптовых языках есть тема! обычно оптимальна с точки зрения скорости выполнения. Под катом пример реализации приложения на python+PyQt4, функции приложения парсинг и загрузка данных из xls файлов...
Для того чтобы приготовить яичницу я использовал:
  1. Python2.5
  2. PyQt-4.4.3
  3. kinterbasdb3 (БД КИС — Firebird)
  4. xlrd-0.6
В качестве редактора всем рекомендую emacs python-mode (это касается и
виндопользователей):

emsc python-mode

1. Достаем посуду из шкафа (хранение настроек)


Вообще для скриптовых языков такой вопрос не стоит так как, вы можете завести файл настроек типа settings.py и спокойно запускать его на уровне кода:
# -*- coding: cp1251 -*-
host='localhost/3051:intur'
user='SYSDBA'
path='d:\\dlogs\\scanner\\xls'

oprts = (
u'НАТАЛИ',
u'ЭКСПРЕСС',
u'ИНТАЕР',
u'ЛАНТА',
u'КОРАЛ',
)

Получение переменных в программе выглядит так:
mod = __import__(modName)
host = getattr(mod, 'host', 'horn:intur')
user = getattr(mod, 'user', 'SYSDBA')

2.Рисование форм


Qt Software — вообще красавцы с точки зрения документации, или если сравнивать тулзы для рисования GUI — то здесь они тоже молодцы. Главное окошко программы я нарисовал в QtDesigner + отметил сигналы с виджетов, которые нужно обрабатывать.
emsc python-mode
Для того чтобы быстро собирать формы в дизайнере безусловно нужно немного поднатореть в понимание механизмов формирования Layout и Spacers. Существует два варианта поднятия окошка в приложения, либо вы генерируете файл необходимом для вас языке программирования, либо с помощью спец.модулей Qt строите классы из xml-файлов описания. Я обычно генерирую файл, не могу сказать что это чем-то лучше, просто мне это кажется более удобным. Для питона PyQt поставляет pyuic.bat который просто нужно скопировать в директорию вашего проекта и генерировать классы-обработчики окошек по мере вашей работы в дизайнере
У меня это для главного окна выглядит так:

       pyuic.bat -o mwnd.py mwnd.ui

В отличие от wx Qt генеруют не наследники классов главных окон, а классы- модификаторы которые получают в качестве аргумента базовый класс окна и «вешают» на него ваши контролы. При генерации на с++ Qt использует множественное наследование класс вашего приложения становится наследником класса базового окна и класса-модификатора. Интересно что при генерации файлов слоты pyuic вешаются на базовый класс, отсюда несоответствие — обработчики сигналов находятся в наследнике базового класса окна, а ссылки на контролы этого же окна находятся у класса-модификатора сгенерированного pyuic.

    def _initApp(self):
        self.mwnd, self.mwnd.ui = MainWnd(), Uwnd()
        self.mwnd.ui.setupUi(self.mwnd)

Я поступил просто: связал класс-модификатор с наследником базового класса окна, получилось просто при необходимости обращения к контролам общаюсь к ним как — self.ui.«name». Вроде очевидная штука, но как часто это бывает пришла ко мне в голову не с первого раза.

! Еще интересно что в питон не переваривает ключевые слова в названиях атрибутов и методов классов, поэтому вы не можете завести переменную self.pass или self.exec(). Отсюда и смешная надпись в каждой PyQt приложении sys.exit(app.exec_())

3. Ставим скороводку на плиту, или запуск приложения


Вот код main.py — его задачи запуститься, загрузить файл настроек, запросить пароль и в случае удачного подключения запустить главное окно приложения

main.py

4. Не забудем положить яица в яичницу.


Наследник главного окна приложения (MainWnd) выполняет функции отслеживания поведения пользователя, здесь кстати видны слоты которые мы сгенерировали в дизайнере, здесь основная задача кода максимально прозрачные и простые функции управления окном для основного класса приложения выполняющего загрузку файла в БД.
Класс выполняющий основную функцию приложения — парсинг и загрузку данных (MainModel) не имеет смысла без главного окна поэтому сделаем его атрибутом окна. Для парсинга xls файлов в питоне есть тривиальная в использовании, и тем замечательная библиотека xlrd, работает с файлом напрямую не поднимая громоздких OLE машин, и поэтому еще и более быстродейственна. Приложение позволяет загружать в режиме только измененных файлов, поэтому часть когда MainModel, уведено для сравнения дат модификации и последней загрузки, которая хранится в БД. Так кроме главного рабочего класса приложения никто с БД не общается даем ему небольшой класс (dbConn), которые хранит инструкции MainModel в «терминах» sql.

WndModel.py

Вообще по науке, есть некая неуклюжесть программы из-за протягивания переменных (например app) с класса Container до классов 2 уровня иерархий. В больших программах таких переменных становится чуть более чем 9000 много, и эта задача решается с помощью синглтона (в следующий раз это я учту).

В итоге мы получили шаблон приложения, который вы можете использовать в своих целях, выбрасываете WndModel.py, пишите свой наследник базового окна, свой класс реализующий ваши задачи — и вроде бы все теперь оно даже работает.

P.S. Полный исходный код здесь

UPD. вынес код на внешний кодохранитель, если кто подскажет как корректно подсветить python-код на Хабре буду благодарен.
Tags:
Hubs:
+23
Comments24

Articles

Change theme settings