Часто приходится разрабатывать приложения для корпоративной системы которые должны были функционировать еще вчера, не требующие строго соответствия корпоративным стандартам. Такими приложениями могут представлять cms к сайтам, gui для сервисов под *nix системы просто приложением учетной системы. Разработка приложений подобного рода на скриптовых языках есть тема! обычно оптимальна с точки зрения скорости выполнения. Под катом пример реализации приложения на python+PyQt4, функции приложения парсинг и загрузка данных из xls файлов...
Для того чтобыприготовить яичницу я использовал:
виндопользователей):
Вообще для скриптовых языков такой вопрос не стоит так как, вы можете завести файл настроек типа settings.py и спокойно запускать его на уровне кода:
Получение переменных в программе выглядит так:
Qt Software — вообще красавцы с точки зрения документации, или если сравнивать тулзы для рисования GUI — то здесь они тоже молодцы. Главное окошко программы я нарисовал в QtDesigner + отметил сигналы с виджетов, которые нужно обрабатывать.
Для того чтобы быстро собирать формы в дизайнере безусловно нужно немного поднатореть в понимание механизмов формирования Layout и Spacers. Существует два варианта поднятия окошка в приложения, либо вы генерируете файл необходимом для вас языке программирования, либо с помощью спец.модулей Qt строите классы из xml-файлов описания. Я обычно генерирую файл, не могу сказать что это чем-то лучше, просто мне это кажется более удобным. Для питона PyQt поставляет pyuic.bat который просто нужно скопировать в директорию вашего проекта и генерировать классы-обработчики окошек по мере вашей работы в дизайнере
У меня это для главного окна выглядит так:
В отличие от wx Qt генеруют не наследники классов главных окон, а классы- модификаторы которые получают в качестве аргумента базовый класс окна и «вешают» на него ваши контролы. При генерации на с++ Qt использует множественное наследование класс вашего приложения становится наследником класса базового окна и класса-модификатора. Интересно что при генерации файлов слоты pyuic вешаются на базовый класс, отсюда несоответствие — обработчики сигналов находятся в наследнике базового класса окна, а ссылки на контролы этого же окна находятся у класса-модификатора сгенерированного pyuic.
Я поступил просто: связал класс-модификатор с наследником базового класса окна, получилось просто при необходимости обращения к контролам общаюсь к ним как — self.ui.«name». Вроде очевидная штука, но как часто это бывает пришла ко мне в голову не с первого раза.
! Еще интересно что в питон не переваривает ключевые слова в названиях атрибутов и методов классов, поэтому вы не можете завести переменную self.pass или self.exec(). Отсюда и смешная надпись в каждой PyQt приложении sys.exit(app.exec_())
Вот код main.py — его задачи запуститься, загрузить файл настроек, запросить пароль и в случае удачного подключения запустить главное окно приложения
main.py
Наследник главного окна приложения (MainWnd) выполняет функции отслеживания поведения пользователя, здесь кстати видны слоты которые мы сгенерировали в дизайнере, здесь основная задача кода максимально прозрачные и простые функции управления окном для основного класса приложения выполняющего загрузку файла в БД.
Класс выполняющий основную функцию приложения — парсинг и загрузку данных (MainModel) не имеет смысла без главного окна поэтому сделаем его атрибутом окна. Для парсинга xls файлов в питоне есть тривиальная в использовании, и тем замечательная библиотека xlrd, работает с файлом напрямую не поднимая громоздких OLE машин, и поэтому еще и более быстродейственна. Приложение позволяет загружать в режиме только измененных файлов, поэтому часть когда MainModel, уведено для сравнения дат модификации и последней загрузки, которая хранится в БД. Так кроме главного рабочего класса приложения никто с БД не общается даем ему небольшой класс (dbConn), которые хранит инструкции MainModel в «терминах» sql.
WndModel.py
Вообще по науке, есть некая неуклюжесть программы из-за протягивания переменных (например app) с класса Container до классов 2 уровня иерархий. В больших программах таких переменных становится чуть более чем9000 много, и эта задача решается с помощью синглтона (в следующий раз это я учту).
В итоге мы получили шаблон приложения, который вы можете использовать в своих целях, выбрасываете WndModel.py, пишите свой наследник базового окна, свой класс реализующий ваши задачи — и вроде бы все теперь оно даже работает.
P.S. Полный исходный код здесь
UPD. вынес код на внешний кодохранитель, если кто подскажет как корректно подсветить python-код на Хабре буду благодарен.
Для того чтобы
- Python2.5
- PyQt-4.4.3
- kinterbasdb3 (БД КИС — Firebird)
- xlrd-0.6
виндопользователей):
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 + отметил сигналы с виджетов, которые нужно обрабатывать.
Для того чтобы быстро собирать формы в дизайнере безусловно нужно немного поднатореть в понимание механизмов формирования 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 уровня иерархий. В больших программах таких переменных становится чуть более чем
В итоге мы получили шаблон приложения, который вы можете использовать в своих целях, выбрасываете WndModel.py, пишите свой наследник базового окна, свой класс реализующий ваши задачи — и вроде бы все теперь оно даже работает.
P.S. Полный исходный код здесь
UPD. вынес код на внешний кодохранитель, если кто подскажет как корректно подсветить python-код на Хабре буду благодарен.