Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Пишем плагин для XBMC с собственным интерфейсом: часть II — диалоги и украшателства

Anna | 16.06.2014 | нет комментариев

Введение

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

Выходит, перейдем к диалогам.

Диалоги

В различие от контролов, диалоги не требуют родительского класса-контейнера и могут быть вызваны непринужденно путем создания экземпляра соответствующего класса с дальнейшим обращением к надобному способу. Второе различие заключается в том, что диалоги механически применяют нужные текстуры из нынешнего скина, т. е. нам не нужно заботиться об их визуальном оформлении. Функционально диалоги XBMC UI напоминают модальные диалоги tkFileDialog/tkMessageBox в Tkinter либо диалоги-преемники QDialog в PyQt.

Множество диалогов, помимо 2-х, представляют собой способы класса xbmcgui.Dialog. По-типичному, безусловно, следовало бы реализовать эти диалоги в виде статических способов либо вообще примитивных функций, но в XBMC API, к сожалению, не все вещи сделаны по-типичному, следственно для обращения к диалогам необходимо заранее сделать экземпляр класса xbmcgui.Dialog, через тот, что будет осуществляться обращение к необходимым диалогам.

Диалоги xbmcgui.Dialog

Дальше будут рассмотрены диалоги, реализуемые посредством способов класса xbmcgui.Dialog.

browse

Диалог выбора файлов и папок. Имеет много параметров, дозволяющих настроить режим выбора: файл, папка, множественный выбор и т. п.
Возвращает строку, содержащую путь к файлу либо папке, либо кортеж строк с путями в зависимости от режима выбора.
Не вовсе явственный момент: 3-й параметр вызова (s_shares) представляет собой один из тэгов файла userdatasources.xml: video, music, pictures либо files. Первые 3 варианта применяются для доступа к источникам видео, музыки и фото соответственно, а параметр files открывает доступ к дискам/папкам, добавленным в администратор файлов. Если администратор файлов пустой, открывается доступ ко каждой файловой системе.
Пример:

dialog = xbmcgui.Dialog()
path = dialog.browse(1, 'Select file', 'video', '.avi|.mkv|.mp4')
browseMultiple

Подвид предыдущего способа. Реализует множественный выбор. Возвращает кортеж строк с путями.

browseSingle

Тоже подвид browse для выбора одного файла/папки. Возвращает путь в виде строки.

input

Диалог ввода с виртуальной клавиатурой. Имеет различные режимы: ввод текста, чисел, даты, времени и т. п. Возвращает введенные данные в виде строки.

numeric

Подвид предыдущего диалога, разрешающий вводить числовую информацию. Также возвращает введенное значение в виде строки.

notification

Выводит всплывающее уведомление в интерфейсе XBMC. Расположение уведомления зависит от нынешнего скина. В Confluence это правый нижний угол.

yesno

Диалог с кнопками «Да» и «Нет». Возвращает True при выборе «Да».

ok

Диалог с кнопкой «ОК». Возвращает True при нажатии «ОК».

select

Список текстовых строк для выбора одного элемента из некоторого комплекта. При большом числе строк список прокручивается. Возвращает номер выбранной строки, начиная с 0, либо -1, если диалог был закрыт нажатием ESC (либо иной кнопки, реализующей отмену действия).

Дальше два диалога, не являющиеся способами Dialog.

DialogProgress

Класс DialogProgress реализует диалоговое окно с прогресс-баром, показывающим ход выполнения некоторого процесса.

DialogProgressBG

«Фоновое» окно с прогресс-баром. Обыкновенно отображается в правом верхнем углу интерфейса.

Как мы видим, диалоги дополняют вероятности контролов. Комбинируя различные контролы и диалоги, дозволено реализовать довольно трудное взаимодействие с пользователем.

Добавляем украшательства и интерактивные элементы

Дальше разглядим немножко больше трудные примеры, чем легкой «Здравствуй, мир!» в предыдущей части. Для украшения интерфейса нам потребуются картинки и текстуры. Как упоминалось в I части, в исходниках скинов дозволено обнаружить довольно широкий комплект картинок и текстур. Текстуры для приведенных ниже примеров взяты из исходников скина Confluence, а картинку с танцующим бананом я обнаружил на просторах Интернета.

Пример на базе класса Window

Начнем, безусловно же, с файла addon.xml.

Содержимое addon.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.test.buttons"
   name="Buttons test script"
   version="0.0.1"
   provider-name="Roman_V_M">
  <requires>
    <import addon="xbmc.python" version="2.0"/>
  </requires>
  <extension point="xbmc.python.script" library="default.py">
    <provides>executable</provides>
  </extension>
  <extension point="xbmc.addon.metadata">
    <platform>all</platform>
    <summary lang="en">Buttons test script</summary>
    <description lang="en">My buttons test script.</description>
  </extension>
</addon>

Сейчас переходим непринужденно к коду плагина.

default.py

# -*- coding: utf-8 -*-
# Licence: GPL v.3 http://www.gnu.org/licenses/gpl.html

# Имортируем модули стандартной библиотеки.
import os, sys
# Импортируем модули XBMC.
import xbmcgui, xbmcaddon

# Создаем экземпляр класса Addon для доступа к параметрам плагина.
# Если имя плагина в xbmcaddon.Addon() очевидно не указано,
# мы получаем параметры нынешнего плагина.
_addon = xbmcaddon.Addon()
# Получаем путь к плагину.
_addon_path = _addon.getAddonInfo('path').decode(sys.getfilesystemencoding())

# Коды клавиатурных команд.
ACTION_PREVIOUS_MENU = 10 # Esc
ACTION_NAV_BACK = 92 # Backspace

# Параметр выравнивания текста.
ALIGN_CENTER = 6

# Указываем пути к картинкам и текстурам:
# фон;
background_img = os.path.join(_addon_path, 'images', 'SKINDEFAULT.jpg')
# текстура кнопки без фокуса;
button_nf_img = os.path.join(_addon_path, 'images', 'KeyboardKeyNF.png')
# текстура кнопки в фокусе;
button_fo_img = os.path.join(_addon_path, 'images', 'KeyboardKey.png')
# танцующий банан чисто для прикола :-) .
banana_img = os.path.join(_addon_path, 'images', 'banana.gif')

class MyAddon(xbmcgui.Window):

    def __init__(self):
        # Создаем экземпляр класса Dialog для доступа к диалогам.
        self.dialog = xbmcgui.Dialog()
        # Устанавливаем фоновую картинку.
        background = xbmcgui.ControlImage(1, 1, 1280, 720, background_img)
        self.addControl(background)
        # Размещаем картинку с бананом.
        banana_picture = xbmcgui.ControlImage(500, 200, 256, 256, banana_img)
        self.addControl(banana_picture)
        # Создаем интерактивные контролы (кнопки).
        self.set_controls()
        # Настраиваем навигацию между контролами.
        self.set_navigation()

    def set_controls(self):
        # Кнопка "Здравствуй".
        self.privet_btn = xbmcgui.ControlButton(500, 500, 110, 40, u'Привет…', focusTexture=button_fo_img,
                                                        noFocusTexture=button_nf_img, alignment=ALIGN_CENTER)
        self.addControl(self.privet_btn)
        # Кнопка "Выход".
        self.exit_btn = xbmcgui.ControlButton(650, 500, 110, 40, u'Выход', focusTexture=button_fo_img,
                                                        noFocusTexture=button_nf_img, alignment=ALIGN_CENTER)
        self.addControl(self.exit_btn)

    def set_navigation(self):
        # Назначаем соседние контролы для кнопки "Здравствуй".
        self.privet_btn.controlRight(self.exit_btn)
        self.privet_btn.controlLeft(self.exit_btn)
        # Назначаем соседние контролы для кнопки "Выход".
        self.exit_btn.controlRight(self.privet_btn)
        self.exit_btn.controlLeft(self.privet_btn)
        # Устанавливаем изначальный фокус на кнопку "Здравствуй".
        self.setFocus(self.privet_btn)

    def onAction(self, action):
        # Обрабатываем нажатия кнопок для выхода из плагина.
        if action == ACTION_NAV_BACK or action == ACTION_PREVIOUS_MENU:
            self.close()

    def onControl(self, control):
        # Обрабатываем активированные контролы.
        # Если активирована кнопка "Здравствуй"...
        if control == self.privet_btn:
            # ...выводим диалоговое окно с надписью и кнопкой ОК.
            self.dialog.ok(u'Прversion="0.0.1"
   provider-name="Roman_V_M">
  <requires>
    <import addon="xbmc.python" version="2.0"/>
  </requires>
  <extension point="xbmc.python.script" library="default.py">
    <provides>executable</provides>
  </extension>
  <extension point="xbmc.addon.metadata">
    <platform>all</platform>
    <summary lang="en">Buttons test script</summary>
    <description lang="en">My buttons test script.</description>
  </extension>
</addon>

Дальше сам код.

default.py

# -*- coding: utf-8 -*-
# Licence: GPL v.3 http://www.gnu.org/licenses/gpl.html

# Имортируем модули стандартной библиотеки.
import os, sys
# Импортируем модули XBMC.
import xbmcgui, xbmcaddon

# Создаем экземпляр класса Addon для доступа к параметрам плагина.
# Если имя плагина в xbmcaddon.Addon() очевидно не указано,
# мы получаем параметры нынешнего плагина.
_addon = xbmcaddon.Addon()
# Получаем путь к плагину.
_addon_path = _addon.getAddonInfo('path').decode(sys.getfilesystemencoding())

# Коды клавиатурных комманд.
ACTION_PREVIOUS_MENU = 10 # Esc
ACTION_NAV_BACK = 92 # Backspace

# Параметр выравнивания текста.
ALIGN_CENTER = 6

# Указываем пути к картинкам и текстурам:
# фон;
background_img = os.path.join(_addon_path, 'images', 'ContentPanel.png')
# текстура кнопки без фокуса;
button_nf_img = os.path.join(_addon_path, 'images', 'KeyboardKeyNF.png')
# текстура кнопки в фокусе;
button_fo_img = os.path.join(_addon_path, 'images', 'KeyboardKey.png')
# танцующий банан чисто для прикола :-) .
banana_img = os.path.join(_addon_path, 'images', 'banana.gif')

class MyAddon(xbmcgui.WindowDialog):

    def __init__(self):
        # Создаем экземпляр класса Dialog для доступа к диалогам.
        self.dialog = xbmcgui.Dialog()
        # Устанавливаем фоновую картинку.
        background = xbmcgui.ControlImage(370, 100, 500, 500, background_img)
        self.addControl(background)
        # Размещаем картинку с бананом.
        banana_picture = xbmcgui.ControlImage(500, 200, 256, 256, banana_img)
        self.addControl(banana_picture)
        # Создаем интерактивные контролы (кнопки).
        self.set_controls()
        # Настраиваем навигацию между контролами.
        self.set_navigation()

    def set_controls(self):
        # Кнопка "Здравствуй".
        self.privet_btn = xbmcgui.ControlButton(500, 500, 110, 40, u'Привет…', focusTexture=button_fo_img,
                                                        noFocusTexture=button_nf_img, alignment=ALIGN_CENTER)
        self.addControl(self.privet_btn)
        # Кнопка "Выход".
        self.exit_btn = xbmcgui.ControlButton(650, 500, 110, 40, u'Выход', focusTexture=button_fo_img,
                                                        noFocusTexture=button_nf_img, alignment=ALIGN_CENTER)
        self.addControl(self.exit_btn)

    def set_navigation(self):
        # Назначаем соседние контролы для кнопки "Здравствуй".
        self.privet_btn.controlRight(self.exit_btn)
        self.privet_btn.controlLeft(self.exit_btn)
        # Назначаем соседние контролы для кнопки "Выход".
        self.exit_btn.controlRight(self.privet_btn)
        self.exit_btn.controlLeft(self.privet_btn)
        # Устанавливаем изначальный фокус на кнопку "Здравствуй".
        self.setFocus(self.privet_btn)

    def onAction(self, action):
        # Обрабатываем нажатия кнопок для выхода из плагина.
        if action == ACTION_NAV_BACK or action == ACTION_PREVIOUS_MENU:
            self.close()

    def onControl(self, control):
        # Обрабатываем активированные контролы.
        # Если активирована кнопка "Здравствуй"...
        if control == self.privet_btn:
            # ...выводим диалоговое окно с надписью и кнопкой ОК.
            self.dialog.ok(u'Здравствуй, мир!', u'Я рад тебя видеть :-) ')
        # Если активирована кнопка "Выход", выходим из плагина.
        elif control == self.exit_btn:
            self.close()

if __name__ == '__main__':
    addon = MyAddon()
    addon.doModal()
    del addon

По сопоставлению с предыдущим примером изменились каждого 3 строчки.
25: иная текстура фона.
33: наследуем от WindowDialog.
39: другие координаты и размеры фоновой картинки.

Проверяем итог.

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

Всецело плагин из данного примера дозволено скачать отсель.

Завершение

Во II части цикла статей о создании плагинов для XBMC с собственным интерфейсом я рассказал о диалогах, а также привел два касательно примитивных примера плагинов, использующих текстуры для оформления интерфейса и имеющих примитивные интерактивные элементы.
В III части я планирую немножко затронуть вопросы взаимодействия плагинов с XBMC посредством различных API, а также приведу касательно трудный пример видео-плагина с собственным интерфейсом, использующего написанный мной микро-фреймоворк, упрощающий размещение контролов на экране.

Источники информации

Короткая документация XBMC Python API.
HOW-TO:Write Python Scripts for XBMC.

Предыдущие статьи

Подробная анатомия простого плагина для XBMC.
Пишем плагин для XBMC с собственным интерфейсом: часть I — теория и примитивный пример.

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB