2013-10-03, 12:17
I'm glad to present you PyXBMCt — a framework which simplifies creating arbitrary UIs for Kodi addons. UIs based on PyXBMCt may not be so fancy as skinned UIs based on WindowXML, but, in my opinion, it is relatively easy to learn, especially for those who are familiar with general-purpose Python GUI frameworks, like Tkinter, PyQt, PySide etc. And it does not require the knowledge of Kodi skinning, so it's a good choice for beginners.
Introduction
PyXBMCt is a Python framework for simple Kodi (formerly XBMC) addon UI building. It was inspired by PyQt (hence the name) and shares the same basic principles, so those who are familiar with PyQt/PySide should feel themselves right at home. The framework provides 4 base classes, 9 ready-to-use widgets or, in Kodi terms, Controls, a Grid Layout and the event connection function.
PyXBMCt uses texture images from XBMC’s default Confluence skin to decorate its visual elements. Those textures are included in PyXBMCt, so UI based on it will have the same look in different skins.
Base Classes
PyXBMCt provides 4 base classes: AddonDialogWindow, BlankDialogWindow (both based on xbmcgui.WindowDialog), AddonFullWindow and BlankFullWindow (both based on xbmcgui.Window). These classes serve as containers for other UI elements (controls). All base classes are “new-style” Python classes.
AddonDialogWindow class is based on xbmcgui.WindowDialog and provides a parent interface window with a background and a title-bar. The window is always displayed on top of XBMC UI.
AddonFullWinow is based on xbcmgui.Window class. It is similar to AddonDialogWindow and also provides a parent window for other UI controls. But, unlike AddonDialogWindow, it has a solid main background, which covers XBMC UI completely, and can hide under video or music visualization. The default Confluence background is used as the standard background for AddonFullWinow, but it can be changed to any image.
BlankDialogWindow and BlankFullWindow are based on xbmcgui.WindowDialog and xbmcgui.Window respectively. They have no visual elements whatsoever and are meant for DIY developers who want full control over the visual appearance of their addons.
Controls
PyXBMCt provides 9 ready-to-use UI controls — Label, FadeLabel, TextBox, Image, Button, RadioButton, Edit, List and Slider — that are based on the respective xbmcgui controls with the following differences:
- You don’t need to specify coordinates and size for the controls explicitly. The Grid layout manager takes care of control placement.
- All controls that require textures are provided with default textures (borrowed from Confluence skin resources). You can specify your own textures for PyXBMCt controls, but you need to do this through keyword arguments (important!).
- Button caption is center-aligned by default. You can change button caption alignment by providing a necessary alignment parameter through a keyword argument (PyXBMCt already includes symbolic constants for control text alignment).
A screenshot with all PyXBMCt controls:

Grid Layout
The Grid Layout helps to place UI controls within the parent window. It is similar to PyQt’s QGridLayout or Tkniter’s Grid geometry manager. The Grid Layout is implemented through setGeometry and placeControl methods of a base PyXBMCt class. To place a control you simply provide it as the 1st positional argument to placeControl then specify a row and a column for the control as the next arguments, and the control will be placed in a specific grid cell.
Note that row and column numbers start from zero, i.e. the top-left cell will have row# = 0, column# = 0.
Warning: currently PyXBMCt does not support changing window geometry at runtime so you must call setGeometry method only once.
Connecting Events
Event connecting works similarly to the signal-slot connection mechanism of Qt framework. You can connect an event — a control or a key action code — to a function or a method to be called when the respective control is activated or when a key is pressed, thus invoking the key action bound to it. The event connecting function is implemented through connect method of a base PyXBMCt class.
You can only connect the following controls: Button, RadioButton and List. Other controls do not generate any UI events, so connecting them won’t have any effect.
Note that for connection you must provide a function object without brackets (), not a function call!!!. Similarly to PyQt’s signal-slot connection, lambda can be used to connect a function/method with arguments known at runtime.
The key code ACTION_PREVIOUS_MENU or 10 (bound to ESC key by default) is already connected to the method which closes a current addon window (close), so you cannot connect it to any function/method. It guarantees that you can always close an active addon window without killing XBMC.
How to use PyXBMCt
To import PyXBMCt classes and constants into your addon, add the following statement to your addon code:
PyXBMCt Python module is included in the official XBMC Gotham repo, so to use it you need to add the following line into the 'requires' section of your addon.xml:
Then when your addon is installed, PyXBMCt module should also be installed automatically from XBMC official repo.
Note: Since PyXBMCt is included in the official Kodi repo, the local version is depreciated.
Now a simple example without using OOP:
The same example in OOP fashion:
The result:

By default a window is placed at the center of the screen, unless you provide explicit coordinates of the top-left corner to setGeometry method. Note that window width, height and coordinates are specified in XBMC UI coordinate grid pixels. By default, the resolution of the XBMC UI coordinate grid is 1280x720 regardless of you actual display resolution and aspect.
Links
PyXBMCt developer's documentation: http://romanvm.github.io/script.module.pyxbmct
PyXBMCt module repository on Github: https://github.com/romanvm/script.module.pyxbmct
A demo addon with a comprehensive usage example of all PyXBMCt controls: https://github.com/romanvm/pyxbmct.demo
The example of a multi-select dialog based on PyXBMCt.
Your comments, suggestions and questions are welcomed.
Introduction
PyXBMCt is a Python framework for simple Kodi (formerly XBMC) addon UI building. It was inspired by PyQt (hence the name) and shares the same basic principles, so those who are familiar with PyQt/PySide should feel themselves right at home. The framework provides 4 base classes, 9 ready-to-use widgets or, in Kodi terms, Controls, a Grid Layout and the event connection function.
PyXBMCt uses texture images from XBMC’s default Confluence skin to decorate its visual elements. Those textures are included in PyXBMCt, so UI based on it will have the same look in different skins.
Base Classes
PyXBMCt provides 4 base classes: AddonDialogWindow, BlankDialogWindow (both based on xbmcgui.WindowDialog), AddonFullWindow and BlankFullWindow (both based on xbmcgui.Window). These classes serve as containers for other UI elements (controls). All base classes are “new-style” Python classes.
AddonDialogWindow class is based on xbmcgui.WindowDialog and provides a parent interface window with a background and a title-bar. The window is always displayed on top of XBMC UI.
AddonFullWinow is based on xbcmgui.Window class. It is similar to AddonDialogWindow and also provides a parent window for other UI controls. But, unlike AddonDialogWindow, it has a solid main background, which covers XBMC UI completely, and can hide under video or music visualization. The default Confluence background is used as the standard background for AddonFullWinow, but it can be changed to any image.
BlankDialogWindow and BlankFullWindow are based on xbmcgui.WindowDialog and xbmcgui.Window respectively. They have no visual elements whatsoever and are meant for DIY developers who want full control over the visual appearance of their addons.
Controls
PyXBMCt provides 9 ready-to-use UI controls — Label, FadeLabel, TextBox, Image, Button, RadioButton, Edit, List and Slider — that are based on the respective xbmcgui controls with the following differences:
- You don’t need to specify coordinates and size for the controls explicitly. The Grid layout manager takes care of control placement.
- All controls that require textures are provided with default textures (borrowed from Confluence skin resources). You can specify your own textures for PyXBMCt controls, but you need to do this through keyword arguments (important!).
- Button caption is center-aligned by default. You can change button caption alignment by providing a necessary alignment parameter through a keyword argument (PyXBMCt already includes symbolic constants for control text alignment).
A screenshot with all PyXBMCt controls:

Grid Layout
The Grid Layout helps to place UI controls within the parent window. It is similar to PyQt’s QGridLayout or Tkniter’s Grid geometry manager. The Grid Layout is implemented through setGeometry and placeControl methods of a base PyXBMCt class. To place a control you simply provide it as the 1st positional argument to placeControl then specify a row and a column for the control as the next arguments, and the control will be placed in a specific grid cell.
Note that row and column numbers start from zero, i.e. the top-left cell will have row# = 0, column# = 0.
Warning: currently PyXBMCt does not support changing window geometry at runtime so you must call setGeometry method only once.
Connecting Events
Event connecting works similarly to the signal-slot connection mechanism of Qt framework. You can connect an event — a control or a key action code — to a function or a method to be called when the respective control is activated or when a key is pressed, thus invoking the key action bound to it. The event connecting function is implemented through connect method of a base PyXBMCt class.
You can only connect the following controls: Button, RadioButton and List. Other controls do not generate any UI events, so connecting them won’t have any effect.
Note that for connection you must provide a function object without brackets (), not a function call!!!. Similarly to PyQt’s signal-slot connection, lambda can be used to connect a function/method with arguments known at runtime.
The key code ACTION_PREVIOUS_MENU or 10 (bound to ESC key by default) is already connected to the method which closes a current addon window (close), so you cannot connect it to any function/method. It guarantees that you can always close an active addon window without killing XBMC.
How to use PyXBMCt
To import PyXBMCt classes and constants into your addon, add the following statement to your addon code:
PHP Code:
import pyxbmct
Code:
<requires>
...
<import addon="script.module.pyxbmct" version="1.1.4"/>
...
</requires>
Note: Since PyXBMCt is included in the official Kodi repo, the local version is depreciated.
Now a simple example without using OOP:
PHP Code:
# Import PyXBMCt module.
import pyxbmct
# Create a window instance.
window = pyxbmct.AddonDialogWindow('Hello, World!')
# Set the window width, height and the grid resolution: 2 rows, 3 columns.
window.setGeometry(350, 150, 2, 3)
# Create a text label.
label = pyxbmct.Label('This is a PyXBMCt window.', alignment=pyxbmct.ALIGN_CENTER)
# Place the label on the window grid.
window.placeControl(label, 0, 0, columnspan=3)
# Create a button.
button = pyxbmct.Button('Close')
# Place the button on the window grid.
window.placeControl(button, 1, 1)
# Set initial focus on the button.
window.setFocus(button)
# Connect the button to a function.
window.connect(button, window.close)
# Connect a key action to a function.
window.connect(pyxbmct.ACTION_NAV_BACK, window.close)
# Show the created window.
window.doModal()
# Delete the window instance when it is no longer used.
del window
The same example in OOP fashion:
PHP Code:
# Import PyXBMCt module.
import pyxbmct
class MyWindow(pyxbmct.AddonDialogWindow):
def __init__(self, title=''):
# You need to call base class' constructor.
super(MyWindow, self).__init__(title)
# Set the window width, height and the grid resolution: 2 rows, 3 columns.
self.setGeometry(350, 150, 2, 3)
# Create a text label.
label = pyxbmct.Label('This is a PyXBMCt window.', alignment=pyxbmct.ALIGN_CENTER)
# Place the label on the window grid.
self.placeControl(label, 0, 0, columnspan=3)
# Create a button.
button = pyxbmct.Button('Close')
# Place the button on the window grid.
self.placeControl(button, 1, 1)
# Set initial focus on the button.
self.setFocus(button)
# Connect the button to a function.
self.connect(button, self.close)
# Connect a key action to a function.
self.connect(pyxbmct.ACTION_NAV_BACK, self.close)
# Create a window instance.
window = MyWindow('Hello, World!')
# Show the created window.
window.doModal()
# Delete the window instance when it is no longer used.
del window
The result:

By default a window is placed at the center of the screen, unless you provide explicit coordinates of the top-left corner to setGeometry method. Note that window width, height and coordinates are specified in XBMC UI coordinate grid pixels. By default, the resolution of the XBMC UI coordinate grid is 1280x720 regardless of you actual display resolution and aspect.
Links
PyXBMCt developer's documentation: http://romanvm.github.io/script.module.pyxbmct
PyXBMCt module repository on Github: https://github.com/romanvm/script.module.pyxbmct
A demo addon with a comprehensive usage example of all PyXBMCt controls: https://github.com/romanvm/pyxbmct.demo
The example of a multi-select dialog based on PyXBMCt.
Your comments, suggestions and questions are welcomed.
