simakazi 02.03.2011 17:01
Python — Пишем первый плазмоид на Python.
В этом посте я постараюсь максимально доступно описать весь процесс создания простого плазмоида на Python.Я постараюсь показать, что написание своих виджетов - это просто, быстро и полезно!
Для понимания сути происходящего неплохо бы предварительно познать сам Python, поставить KDE ;-), PyKDE, PyQt и поддержку питоновского скриптового движка для плазмы (пакет plasma-scriptengine-python в deb-based дистрибутивах).
Наш первый плазмоид будет выполнять простую функцию: показывать карму пользователя welinux.ru, имя которого было введено в соответствующее поле.
Создание структуры проекта
Во-первых, что же скрывается внутри каждого файла-плазмоида?
На самом деле, любой файл filename.plasmoid является zip-архивом, содержащим внутри себя особую структуру директорий. Начнём с её создания.
Пусть директория нашего проекта будет называться welinux_karmometer. В этой директории надо выполнить команду mkdir -p contents/code. Директория code будет содержать в себе главный скриптовый файл main.py.
В директории contents могут быть представлены следующие поддиректории:
contents/images - содержит изображения, используемые плазмоидом
contents/ui - содержит файлы с разметкой UI (нас не касается, мы пишем на Python)
contents/locale - содержит переводы в установленном формате
contents/config - содержит файлы с настройками в формате KConfigXt
metadata.desktop
Описание плазмоида содержится в файле метаданных metadata.desktop, который находится в корне нашего проекта. Пример такого файла:
Encoding=UTF-8
Name=Welinux karma-meter
Name=Кармометр для Welinux
Comment=Shows user's karma for http://welinux.ru
Comment=Смотри за кармой юзернейма с http://welinux.ru
Icon=/icon.png
Type=Service
ServiceTypes=Plasma/Applet
X-Plasma-API=python
X-Plasma-MainScript=code/main.py
X-KDE-PluginInfo-Author=simakazi
[email protected]
X-KDE-PluginInfo-Name=welinux_karmometer
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Website=http://welinux.ru
X-KDE-PluginInfo-Category=Examples
Остановимся на нём поподробнее.
1. Заголовок файла. Не трогай его, %username%!
2. Значение параметра Encoding менять не стоит, если Вы не старообрядец.
3-4. Параметр Name указывает на название плазмоида, которое будет отображаться в обозревателе плазмоидов. Этот параметр можно перевести на разные языки, указав их в квадратных скобках.
5-6. Значение Comment будет отображено на вкладке About вашего виджета в обозревателе плазмоидов. Этот параметр также можно переводить.
7. Icon указывает на пиктограмму, соответствующую нашему виджету. Показанный в примере путь указывает на файл welinux_karmometer/icon.png. Можно также использовать пиктограммы, поставляющиеся с кедами, например, accessories-calculator.
8-9. Тип описываемого desktop-файла. Говорим, что описываем апплет плазмы.
10. Используемый API. Код плазмоида может быть написан на C++, Python, Ruby и JavaScript. Мы пишем на Python.
11. Путь к главному скриптовому файлу.
12-13. Имя автора и e-mail для связи. E-mail будет подставляться в обозревателе плазмоидов в строку вида "О всех ошибках и багах пишите на %your_email%", учтите это.
14-16. Имя нашего плазмоида в системе, его версия и связанный с ним сайт (например, http://kde-look.org, если планируется там распространять плод трудов своих)
17. Категория, к которой относится наш плазмоид. За полным списком категорий проследуйте сюда.
Более подробное описание структуры пакета плазмы и файла metadata.desktop находится здесь.
main.py
Пришла пора немножечко покодить.
Ниже представлен листинг файла welinux_karmometer/contents/code/main.py:
Разберём этот код подробно.
Во-первых, поддержка плазмы в Python реализована через расширение PyQt и PyKDE, поэтому оба модуля мы включаем в наш скрипт. PyQt4.QtNetwork используется для работы с протоколом http, на работу с плазмой этот модуль не влияет.
За import'ами следует описание нашего класса. Чтобы создать класс, описывающий поведение апплета плазмы, необходимо унаследовать его от plasmascript.Applet и не забыть проинициализировать суперкласс в методе __init__. Всю инициализацию своего виджета следует вынести из __init__ в init, который будет вызван классом Applet после своей инициализации.
В init мы сообщаем, что наш апплет не будет иметь окна настройки, а его размер можно изменять свободно. Далее в качестве фона апплета устанавливается фон, определённый в текущей теме плазмы.
Создание разметки интерфейса начинается с 21й строки.
Особенность плазмоидов в том, что они используют не стандартные виджеты Qt, а свой особый набор виджетов, которые отрисовываются отдельным движком. Полный их список представлен здесь. Но знакомство с Qt упростит понимание происходящего далее.
Сперва мы создадим простой layout (QGraphicsLinearLayout), расположенный вертикально (Qt.Vertical). Плазма использует свои особые классы для разметки из фреймворка Qt Graphics View.
Плазмоид будет состоять из двух виджетов - строки ввода и текстового окна. В строке ввода пользователь будет указывать имя пользователя, а в текстовом окне (после нажатия пользователем Enter'а) будет выводиться карма.
Так что, мы создаём строку ввода Plasma.LineEdit, текстовый браузер Plasma.TextBrowser, и добавляем их в наш layout.
Сам layout применяем ко всему апплету. Если необходима более сложная разметка, то можно добавлять layout'ы друг в друга, и/или использовать QGraphicsGridLayout.
Затем мы устанавливаем размер всего апплета так, чтобы по высоте влезла и строка ввода, и осталось место для вывода кармы.
Далее создаём объект QHttp, который будет использоваться для общения с сайтом.
Пора прикручивать к созданному интерфейсу логику.
Как видно из строк 32-33, соединение сигналов со слотами можно выполнять двумя способами. Оба работоспособны, но второй считается более pythonic.
Итак, при нажатии Enter'а во время ввода в строку lineUsername произойдёт вызов метода lookUp, а при завершении http-запроса, вызовется doneHttp.
Рассмотрим их по порядку.
В lookUp мы просто берём текущее значение из строки ввода и подставляем его в url, далее вызывается метод get класса QHttp, который выполняет асинхронный запрос.
По окончанию запроса будет произведён вызов метода doneHttp, который при наличии ошибки выведет её в текстовый браузер, а при её отсутствии произведёт поиск по результату запроса с помощью простого регулярного выражения.
Важно помнить, что в плазмоидах не следует выполнять тяжёлую обработку больших объёмов данных, делать синхронные запросы к удалённым серверам и т.п., так как подобные безобразия вызывают подвисания плазмы.
Вот и всё. Остаётся только определить метод создания нашего апплета, который будет вызываться плазмой.
Упаковка, установка, отладка
Пришла пора проверить, что же у нас получилось. В директории welinux_karmometer выполните:
zip -r welinux_karmometer.plasmoid *
plasmapkg -i welinux_karmometer.plasmoid
Первая команда создаст zip-архив с текущим каталогом, а вторая установит плазмоид в систему. Если в дальнейшем потребуется заменить уже установленный плазмоид новой версией, запустите plasmapkg с ключом -u.
Для отладочного просмотра плазмоида можно воспользоваться утилитой plasmoidviewer, которая выведет в консоль все возможные ошибки.
Вот и всё. Теперь Вы можете добавить этот плазмоид себе на рабочий стол и гордиться тем, что создали его сами.
P.S. Данная статья является вводной и не покрывает такие "глубокие" темы, как работа с DataEngine, Extender'ами, окном настроек и пр.
Спасибо за замечание! Постарался разбить код на логические блоки.
Плюсанул за интересный пост.
Но питон пока не изучил, КДЕ не пользуюсь (Fluxbox) - отложу до лучших времен.
Но питон пока не изучил, КДЕ не пользуюсь (Fluxbox) - отложу до лучших времен.
Ничего из раздела main.py не понял ))
Мне еще долго до написания таких вроде бы примитивов как плазмоиды. Че плазмоиды на баше не пишутся? Из этих питон самый простой язык?
Ну хоть понял, что эти зеленые циферки вверху - карма. Правда, че они дробные...
Мне еще долго до написания таких вроде бы примитивов как плазмоиды. Че плазмоиды на баше не пишутся? Из этих питон самый простой язык?
Ну хоть понял, что эти зеленые циферки вверху - карма. Правда, че они дробные...
Самый низкий порог вхождения, пожалуй, у Python и JavaScript, но в JavaScript функциональные возможности плазмы поддерживаются не полностью (в KDE 4.4, как в 4.6 - не знаю). Про Ruby ничего не скажу, использовал его давно и мельком.
Для написания плазмоидов очень полезно знать Qt.
Для написания плазмоидов очень полезно знать Qt.
Cпасибо за пост, но у меня почему-то вываливается ошибка при импорте plasmascript :(
Дистрибутив Arch. Использовал для проверки python2 и python3.
>>> from PyKDE4.plasma import plasmascript
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name plasmascript
>>>
Дистрибутив Arch. Использовал для проверки python2 и python3.
>>> from PyKDE4.plasma import plasmascript
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name plasmascript
>>>
его в aur искать? в основных репозиториях нету. Поставил то что выдало по pacman -Ss python | egrep "kde|plasma" (extra/kdebindings-python 4.6.1-1 <�установлен>)
К сожалению, с Arch я не работал, не знаю. В Сусе питоновский скриптовый движок плазмы предоставляется пакетами python-kdebase4 и python-devel.
Upd. Для Арча вот здесь советуют kdebindings-python поставить. Отпишитесь, если поможет.
только что опять проверил - уже plasmascript импортируется без ошибки хотя ничего дополнительно не ставил с того раза - только обновлялся пару раз.
Мало кто знает, но у welinux есть api :D
http://welinux.ru/ajax/r_get?user=USERNAME отдаст json, где есть и рейтинг =)
http://welinux.ru/ajax/r_get?user=USERNAME отдаст json, где есть и рейтинг =)
Только одна просьба: отбивай логические блоки в коде пустыми строками чтоб было понятнее. Потому что ты вот пишешь: ...со строки 19... ...видно из строк 27-28... Найти можно, но из-за того, что все строчки монолитно сливаются в один блок и глазу не за что ухватиться, на поиск требуется время.
Если бы эти логические блоки отделялись друг от друга пустыми строками было бы гораздо удобнее понимать код.