Данный цикл статей является работой одного очень креативного и умного человека с ником Liksys. Благодаря хорошим людям он получил инвайт и продолжение этого цикла статей будет безусловно! ;)

image

Часть №1


       Когда люди говорят о Qt, многим из нас сразу вспоминается KDE с его обилием настроек. Программисты следом представляют исходники, написанные на C++ с весьма изящным подходом к решению проблемы. И это вполне оправданно: KDE — это, пожалуй, самый известный Qt-проект, а сама Qt написана на C++ и предназначена в первую очередь именно для него. За долгое время существования этого инструментария он стал своеобразным стандартом в Linux для написания графических приложений наряду с GTK, wxWidgets и т.д. Мощь языка C++ дала возможность создать много отличных программ, а стиль Qt является образцом для подражания многих программистов.

       Но не все так просто. Ирония заключается в том, что навороченность и функциональность C++ для конечных программ очень часто избыточна. Для написания небольшого приложения приходится выполнять очень много действий, да и использование в коде указателей и прочих «наворотов» C++ наряду со средствами Qt выглядит не очень хорошо. Ведь не всегда программа по сложности сравнима с тем же KDE, который использует все возможности Qt (ему, кстати, их мало, и KDE`шники написали много расширений). Не забудем еще то время, которое тратится на компиляцию программы — из-за этого сильно снижается продуктивность работы.
       Однако в мире OpenSource всегда найдется альтернатива, и тут она тоже есть. Это Python. Python, в отличие от C++, гораздо более прост в изучении, обладает интуитивным и логичным синтаксисом, а его динамическая типизация, автоматическое управление памятью и богатый набор встроенных высокоуровневых типов позволяют писать весьма эффективный и компактный код. Сочетание же Python и Qt4 дает возможность быстро создавать удобные приложения
с графическим интерфейсом.
       Еще одно неоспоримое приемущество Python — его реализация. Можно подумать, что Python — интерпретируемый язык, но это не совсем так. При запуске программы создаются файлы ".pyc"
используемых модулей — это откомпилированный байт-код Python. Компиляция в бай-код происходит автоматически (по возможности) и занимает очень мало времени, в отличие от компиляции в исполняемые файлы с C++ — можно заменить пару строчек и сразу запустить программу — не надо дожидаться окончания сборки программы, все происходит абсолютно незаметно. Это очень удобно
для программиста.
        И наконец, вопрос скорости. Python работает достаточно быстро, поэтому пользователь даже не замечает разницы, а если все-таки хочется ускорить программу, можно применить модуль Psyco — он включает JIT-компиляцию, и производительность программы, выполняющей много вычислений, сразу возрастает.
       Если вам некоторые из всех этих терминов непонятны — не огорчайтесь, по мере чтения я все-все вам объясню. Итак, давайте приступим.
       Мы будем использовать Qt4, потому что она все-таки скоро вытеснит Qt3, да и имеет по сравнению с ней много нововведений, и писать программы гораздо более приятно.
       Реализация Qt4 для Python называется PyQt4 (логично, не так ли?) и производится компанией Riverbank. Распространяется она таким же образом, как и Qt4: по проприетарной лицензии и по GPL. Скачать последню версию можно обычно из репозитория вышего дистрибутива, но если там ее не оказалось, то это можно сделать на сайте www.riverbankcomputing.co.uk. Существуют реализации PyQt4 не только для Linux, но и для MacOSX, Windows. Я, например, часто
пишу программы на Python для Windows (хоть это мне и не нравится, но никого это не волнует). Программы, написаные на Python и Qt4 пересноимы — их легко можно запустить на другой платформе
даже без перекомпиляции!
        PyQt4 предствляет собой «обертку» к библиотеке Qt4, выполненном с помощью SIP — инструментария для создания привязок к библиотекам. Поэтому для работы PyQt4 необходима сама Qt4. Ее так же можно установить из репозитория или с сайта компании Trolltech: www.trolltech.com.
       Установка PyQt4 не должна вызвать трудностей, даже если вы устанавливаете из исходных текстов. Однако я все таки рекомендовал бы поискать в репозиториях вашег�� дистрибутива.
       После установки можно сразу приступить к созданию программ. Думаю, что я уже вас достаточно раззадорил, поэтому давайте напишем парочку простых программ — одну на C++, а вторую — на Python, имспользуя Qt4. Заодно и сравним легкость написания, чтобы мои заявления не выглядели голословными.
       Начнем с C++. Будем работать в консоли, поэтому вам, как настоящему джигиту, необходимо уметь ее обуздать. Типичные действия такие — создать каталог проекта, создать файлы исходных текстов,
создать проектный файл Qt, создать из него Makefile (файл-сценарий для GNU make) и запустить сборку. Затем, если ваши мольбы к небесам были услышаны, вы получите готовый исполняемых файл с именем, как у каталога вашего проекта. Описание выглядит жутковато (я уже не говорю о том, как все это состыковать с файлами, созданными autotools, но это к делу не относится). Итак, открываем консоль.

	[liksys@max ~]$ mkdir helloqt
	[liksys@max ~]$ cd helloqt
	[liksys@max helloqt]$ cat > main.cpp
	#include <QApplication>
	#include <QLabel>
	int main(int argc, char **argv)
	{
		QApplication app(argc, argv);
		QLabel *label = new QLabel("Hello, Qt4!");
		label->show();
		return app.exec();
	}
	<Ctrl+D>
	[liksys@max helloqt]$ qmake-qt4 -project
	[liksys@max helloqt]$ qmake-qt4
	[liksys@max helloqt]$ make
	-Тут идут сообщения компилятора, надеюсь, все прошло успешно-
	[liksys@max helloqt]$ ./helloqt

Вот и наше первое приложение на Qt4. Если вы получили сообщения в духе:

	main.cpp:1:24: error: QApplication: Нет такого файла или каталога
	main.cpp:2:18: error: QLabel: Нет такого файла или каталога
	main.cpp: In function ‘int main(int, char**)’:
	main.cpp:5: ошибка: нет декларации ‘QApplication’ в этой области видимости
	...
	


       то вы использовали утилиты от Qt3, а не от Qt4. Поэтому уточните пути к ним и попробуйте еще раз и используйте qmake-qt4, чем просто qmake (это скорее всего принадлежит к Qt3).
       Процесс немного страшноват, но теперь успокоимся и напишем то же самое на Python. Нам необходимо знать только одно — путь к интерпретатору Python, это можно сделать с помощью команды which. Перейдя в
домашний каталог, сделаем следующее:

	[liksys@max helloqt]$ which python
	/usr/bin/python
	[liksys@max ~]$ mkdir hellopyqt
	[liksys@max ~]$ cd hellopyqt
	[liksys@max hellopyqt]$ cat > hellopyqt
	#!/usr/bin/python
	from PyQt4 import Qt
	import sys
	if __name__ == "__main__" :
		app = Qt.QApplication(sys.argv)
		label = Qt.QLabel("Hello, PyQt4!")
		label.show()
		app.exec_()
	[liksys@max hellopyqt]$ chmod +x hellopyqt
	[liksys@max hellopyqt]$ ./hellopyqt


       Как видно, в случае с Python все намного проще. Просто узнаем путь к интерпретатору, создаем файл с Python-программой и делаем его исполняемым. Все! Теперь можно запустить программу как любую другую.
Давайте разберем подробнее все, что мы сделали, и начнем, пожалуй, с консоли.
       Сначала мы узнали путь к интерпретатору. Для чего? Чтож, если вы ас консоли и знакомы с написанием сценариев оболочки, то сразу поймете, в чем дело. Для тех, кто не знает, объясню. Система не знает, как
запустить на исполнение файл. В UNIX нет привязки к расширению файла, вместо этого используются «Волшебные числа», однозначно идентифицирующие тип файла. Исполняемые бинарные файлы Linux имеют в самом начале определенное волшебное число, по которому система и узнает, что это за файл. Тогда как быть со сценариями (еще один термин, который неплохо бы запомнить, это любой интерпретируемый файл, часто например можно услышать — сценарии оболочки)? Для этого была предусмотрена специальная последовательность символов — "#!", называемая так же «шибенг». После этой последовательности символов указывают путь к программе, которая выполняет сценарий. В данном случае это Python. Программу можно так же запустить и напосредственно вызвав интерпретатор (при этом ваша программа желательно, должна иметь расширение .py, хотя бы для удобочитаемости):

	[liksys@max ~] $ python myprog.py


       Далее мы создали каталог для программы. Вообще говоря, для такой простой программы, как «Hello», делать это было не обязательно, но для больших проектов просто необходим��. Python ищет модули, кроме системных (и заданных пользователем) путей еще и в текущем каталоге, поэтому хорошо бы его как-то ограничить.
       После создания файла мы сделали его исполняемым и запустили. Это стандартные действия, и если до этого вы писали сценарии оболочки, то узнаете эту последовательность комманд.
       Давайте подробнее остановимся на самой программе. Сразу видна разница с аналогом на C++ — визуально программа выглядит проще и занимает немного меньше места.
       Про первую строчку уже было сказано — мы задаем путь к интерпретатору. Следующие две строчки импортируют необходимые модули — это PyQt4 и sys. Модуль sys импортируется полностью, а вот от PyQt4 импортируется только часть — Qt. В нем импортируются автоматически модули QtGui, QtCore и т.д. Конечно, можно импортировать и каждую часть PyQt4 по отдельности, но можно поступить проще, создав таким образом себе меньше проблем (ведь не обязательно помнить, в каком модуле находится нужный класс). Импортируя Qt, мы избавляемся еще и от проблемы совместимости — наши собственные классы не будут конфликтовать с библиотечными. Четвертая строка программы может быть не совсем ясна тем, кто в Python совсем недавно. Модуль Python может исполняться сам по себе (например, при отладке), таким образом, мы включаем код по условию: если файл исполняется, то делаем определенные действия. Если же этот файл прсто импортируется, то эти действия не будут выполняться. За такую магию отвечает переменная __name__, которая содержит имя функции. В нашем «Hello» это было не обязательно, но хороший стиль требует оформления функции main() (как во многих другх языках, например, в C++).
       Затем следует собстенно код, отвечающий за интерфейс. Сначала создается объект-экзампляр QApplication, управляющий всеми ресурсами приложения. Qt сам обрабатывает некоторые опции командной строки, поэтому в качестве параметра мы передаем конструктору sys.argv — список опций, с которыми была запущщена программа.
       В следующей строке создается виджет label — объект-экземпляр класса QLabel. Это текстовая метка, содержащая надпись. Виджет (widget) — это еще один термин, с которым вам часто придется столкнуться. Он
обозначает любой элемент пользовательского интерфейса, например текстовую метку или кнопку. Одни виджеты могут содержать в себе другие виджеты — например, в качестве главного окна часто выступает QMainWindow, содержащий в себе остальные элементы управления. Но никто не принуждает использовать именно QMainWindow, что мы и сделали в предыдущем примере — Qt позволяет использовать любой виджет в качестве окна.
       Если вы знаете HTML (что вообще говоря желательно при работе с Qt) — то можете немного развлечся и заменить текст метки в конструкторе QLabel на "Hello, PyQt4!". Почти все виджеты Qt, работающие тем или иным образом с текстом, поддерживают простейшие средства форматирования HTML.
       Следующая короткая строка — «label.show()», делает наш виджет видимым. В Qt все виджеты по умолчанию создаются невидимыми, чтобы обеспечить возможность их настройки — и затем уде отображаются на экран. Это позволяет избежать мерцания и прочих неприятных эффектов. В большом приложении вам достаточно сделать видимым один главный виджет, а все содержащиеся в нем виджеты станут видимыми автоматически.
       И последняя строка — передача управления приложению6 а именно объекту-экземпляру QApplication. В этом месте программа переходит в цикл обработки событий, ожидая действий со стороны пользователя. Однако мы видим небольшую разницу — в C++ функция называлась exec(), а в Python — exec_(). Почему же это так? В Python существует ключевое слово exec, поэтому разработчики PyQt4 приняли простое правило: если имя оригинальной функции Qt4 совпадает с ключевым словом Python, то после имени функции ставится символ "_". Это правило справедливо для всех функций PyQt4.
       Как видим, на Python программа получилась проще. Никаких заголовочных файлов отдельно для каждого класса, никаких указателей и прочих примудростей C++. Конечно, придется немного привыкнуть к разным премудростям Python, но одно ясно — для программ с графическим интерфейсом Python подходит очень хорошо. Можно создавать программы быстрее и короче, используя всю мощь Qt4 для C++ и удобство Python. Не даром такой подход пользуется популярностью у многих разработчиков, как OpenSource, так и коммерческих компаний, благо Python распространяется по большому количеству лиценизий на любой вкус, заплатить коммерческим компаниям, выпускающим продукты с закрытыми исходными текстами, только за Qt4 и PyQt4. Но мы же пока только учимся, не так ли? Поэтому вполне можем пользоваться этими библиотеками на условиях лицензии GPL, выпуская все наши творения в открытом виде. А закрытый софт — это дело коммерческих компаний, которые могут себе позволить и такое.
       Надеюсь, мне удалось заинтересовать вас, ведь дальше будет еще интереснее! Мы научимся создавать свои приложения на PyQt4, собственные виджеты, я расскажу вам, как правильно располагать модули, использовать такие современные технологии, как интернационализацию. Мы поговорим о том, как следует организовывать приложение
с точки зрения эргономики и дизайна — ведь интерфейс, это важнейшая деталь продукта, именно его видит пользователь перед собой. По мере изучения мы напишем много простых приложений, иллюстрирующих ту или иную концепцию, а в конце попробуем написать что-то интересное, используя весь багаж знаний.
image
Ждите часть №2. Надеюсь вы узнали много нового, спасибо за внимание ;)