Archive:Write python scripts: Difference between revisions

From Official Kodi Wiki
Jump to navigation Jump to search
>DonJ
No edit summary
>Piranna
(change global Python tags to only code, aesthetics)
Line 1: Line 1:
<python>
------------------------------------------------------------------------
------------------------------------------------------------------------
This text version of Alex's tutorial was prepared by Nelson Minar from
This text version of Alex's tutorial was prepared by Nelson Minar from
Line 78: Line 77:
So the first thing to do is to import librairies
So the first thing to do is to import librairies


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui
</python>


After that we create a class including some functions (defined by def)
After that we create a class including some functions (defined by def)


<python>
class MyClass(xbmcgui.Window):
class MyClass(xbmcgui.Window):
   print 'hello world'
   print 'hello world'
</python>


So after that we initialize the class object and doModal() allows to
So after that we initialize the class object and doModal() allows to
Line 89: Line 92:
to have a clean code and delete the class instance.
to have a clean code and delete the class instance.


<python>
mydisplay = MyClass()
mydisplay = MyClass()
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


If you put all this code in a script (called display.py) you'll see an
If you put all this code in a script (called display.py) you'll see an
Line 103: Line 108:
pad for that. Here is the full code:
pad for that. Here is the full code:


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 115: Line 121:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


So now, each time we push the 'BACK' button, we will exit the class.
So now, each time we push the 'BACK' button, we will exit the class.
Line 129: Line 136:
is a 'block' to enable text display on the window:
is a 'block' to enable text display on the window:


<python>
self.strAction = xbmcgui.ControlLabel(300, 520, 200, 200, '', 'font14', '0xFFFFFF00')
self.strAction = xbmcgui.ControlLabel(300, 520, 200, 200, '', 'font14', '0xFFFFFF00')
self.addControl(self.strAction)
self.addControl(self.strAction)
self.strAction.setLabel('BACK to quit')
self.strAction.setLabel('BACK to quit')
</python>


There's a reason to write 3 lines for strAction but we will see it later.
There's a reason to write 3 lines for strAction but we will see it later.
Line 147: Line 156:
button of the pad
button of the pad


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 165: Line 175:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


Don't forget you have to push 'BACK' to stop the script !
Don't forget you have to push 'BACK' to stop the script !
Line 173: Line 184:
We will use the B button to remove the label :
We will use the B button to remove the label :


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 194: Line 206:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


To add text there's also another feature called ControlFadeLabel which
To add text there's also another feature called ControlFadeLabel which
includes a reset function:
includes a reset function:


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 222: Line 236:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>




Line 231: Line 246:
add it in the init function:
add it in the init function:


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 257: Line 273:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


We can also add a background image by including in the init function a ControlImage object:
We can also add a background image by including in the init function a ControlImage object:


<python>
   def __init__(self):
   def __init__(self):
     self.addControl(xbmcgui.ControlImage(0,0,800,600, 'background.png'))
     self.addControl(xbmcgui.ControlImage(0,0,800,600, 'background.png'))
Line 265: Line 283:
     self.addControl(self.strActionInfo)
     self.addControl(self.strActionInfo)
     self.strActionInfo.setLabel('Push BACK to quit, A to display text and B to erase it')
     self.strActionInfo.setLabel('Push BACK to quit, A to display text and B to erase it')
</python>


Of course we display the image before the text :)
Of course we display the image before the text :)
Line 274: Line 293:
What about a dialog box? So we will create function to add a message box :
What about a dialog box? So we will create function to add a message box :


<python>
   def message(self):
   def message(self):
     dialog = xbmcgui.Dialog()
     dialog = xbmcgui.Dialog()
     dialog.ok(" My message title", " This is a nice message ")
     dialog.ok(" My message title", " This is a nice message ")
</python>


And we will call it in another function using self.message()
And we will call it in another function using self.message()


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 305: Line 327:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


So now if you push 'A' a dialog will appear.
So now if you push 'A' a dialog will appear.
Line 310: Line 333:
You can also use the message function in a more general way:
You can also use the message function in a more general way:


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 336: Line 360:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


So now you know how to call a function inside another function :) Be
So now you know how to call a function inside another function :) Be
Line 344: Line 369:
There's also the very common yes / no dialog box :
There's also the very common yes / no dialog box :


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 367: Line 393:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>




Line 378: Line 405:
focus on it:
focus on it:


<python>
self.button0 = xbmcgui.ControlButton(350, 500, 80, 30, "HELLO")
self.button0 = xbmcgui.ControlButton(350, 500, 80, 30, "HELLO")
self.addControl(self.button0)
self.addControl(self.button0)
self.setFocus(self.button0)
self.setFocus(self.button0)
</python>


Then we have to define the action when the button is pushed:
Then we have to define the action when the button is pushed:


<python>
def onControl(self, control):
def onControl(self, control):
   if control == self.button0:
   if control == self.button0:
     print 'button pushed'
     print 'button pushed'
</python>


We can also remove the button of the screen using :  
We can also remove the button of the screen using :  


<python>
self.removeControl(self.button0)
self.removeControl(self.button0)
</python>


As usual here is the code to see Python in action:
As usual here is the code to see Python in action:


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 423: Line 457:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>




Line 430: Line 465:
we have to link the direction between them.
we have to link the direction between them.


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 471: Line 507:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>




Line 478: Line 515:
virtual keyboard.
virtual keyboard.


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 504: Line 542:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>




Line 512: Line 551:
more, so here is an example :
more, so here is an example :


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 545: Line 585:
mydisplay.doModal()
mydisplay.doModal()
del mydisplay
del mydisplay
</python>




Line 553: Line 594:
getWidth()
getWidth()


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 581: Line 623:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>




Line 593: Line 636:
from the init call are displayed first.
from the init call are displayed first.


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 623: Line 667:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay
del mydisplay
</python>




Line 632: Line 677:
and i'm proud enough of the result.
and i'm proud enough of the result.


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 682: Line 728:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay
del mydisplay
</python>


l) How to add a child window ?
l) How to add a child window ?
Line 689: Line 736:
called when the button A is pressed.
called when the button A is pressed.


<python>
import xbmc, xbmcgui
import xbmc, xbmcgui


Line 729: Line 777:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay
del mydisplay
</python>




Line 737: Line 786:
documentation for more infos.
documentation for more infos.


<python>
import xbmc, xbmcgui, urllib
import xbmc, xbmcgui, urllib


Line 772: Line 822:
mydisplay .doModal()
mydisplay .doModal()
del mydisplay  
del mydisplay  
</python>


That's all for now, I hope this guide will help you to understand more
That's all for now, I hope this guide will help you to understand more
Line 778: Line 829:


Alex aka alx5962
Alex aka alx5962
</python>
[[category:Python]]
[[category:Python]]
[[category:Tutorials]]
[[category:Tutorials]]

Revision as of 20:20, 16 April 2007


This text version of Alex's tutorial was prepared by Nelson Minar from the original Word document. Light formatting was applied to make it more readable in text format: no substantial edits. http://www.nelson.monkey.org/~nelson/weblog/


XBOX PYTHON TUTORIAL


This document is released under GPL licence. Written by Alex (aka alx5962 <[email protected]> ) Version 1.2

Please notify me if you notice grammar mistakes (You may have noticed my french accent already :) but please if you can't run some scripts just read this document to understand but don't bug me by email.

I also want to add that I wrote this text with easy understanding in mind and so experienced developers may be irritated by this document, but it's not written for them :)

1/ Python is not a snake

Welcome to this tutorial ! One day I just discovered XBMC (Xbox Media Center) has support for Python. The port is made by Darkie and I'd like to thanks him for his great work and support ( I harrassed him with questions and feature suggestion and he was always nice enough to reply and to add them ). So I thought I could try to use this language to display some basic stuffs.

After many hours spent to understand Python (the snake bite me ;) and read fully the documentation included in the Windows port, I started to code some very basic scripts. Now i'm more comfortable to code so I decided to share my experience.

2/ Some basic rules - be careful of the snake !

You need Python installed on XBMC obviously. Usually it's a python.rar file included with XBMC releases. So unrar it and you'll have 2 folders : python and scripts. They need to be placed in the root directory of XBMC. Some features are added with time and so I really advice you to have the last version of XBMC and Python or some scripts may not work.

The script launcher is based in the parameters settings of XBMC so go there to launch scripts. when you are lauching a script the mention 'running' is added next to the script name. If it still running just click on it then it will stop. After the script is stopped, you can notice debug informations by pressing the white button of your pad. You may need internet access to run some scripts so configure XBMC correctly (read the XBMC doc) and don't forget to edit the nameserver (aka DNS) to resolve domain names.

3/ Always notice the snake behaviour

You must know Python coding is based on indentation. So no need of {} to declare the start and end of a function, class, if... Everything is an object. Very nice sometimes but tricky for beginners! A variable is local unless you declare it global. But this will be clearer in the tutorials. The goal of this document is not to teach Python so I just reccomend you to read the documentation available on www.python.org


4/ the real work begins

There's 2 specific librairies for Python only available on Xbox: xbmc and xbmcgui. They are dedicated to the user interface, and keypad management.

Python code will be coloured in blue I will only talk about scripts including a graphical interface, as the console ones work without xbmc librairies.

a) Window

So the first thing to do is to import librairies

<python> import xbmc, xbmcgui </python>

After that we create a class including some functions (defined by def)

<python> class MyClass(xbmcgui.Window):

 print 'hello world'

</python>

So after that we initialize the class object and doModal() allows to always display the graphical window until we exit it. The del is here to have a clean code and delete the class instance.

<python> mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

If you put all this code in a script (called display.py) you'll see an empty window but as there's no code to exit the Myclass class you'll have to reset the xbox. Also notice the print function only displays infos in debug mode (white button).

b) pad button

So now we need to implant a way to exit the class. So we will use the pad for that. Here is the full code:

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

So now, each time we push the 'BACK' button, we will exit the class. As you can notice, indentation makes everything clear and it's easy to find where everything start or end. def defines a function but here we have a specific one related to XBMC as onAction defines keypad related actions. self.close() will close the window and so the class.

c) add (and remove) text label

Now it's time to display some text on the window we created. For that we will use the ControlLabel function. ControlLabel has some properties including position, colour, transparency, font size. Here is a 'block' to enable text display on the window:

<python> self.strAction = xbmcgui.ControlLabel(300, 520, 200, 200, , 'font14', '0xFFFFFF00') self.addControl(self.strAction) self.strAction.setLabel('BACK to quit') </python>

There's a reason to write 3 lines for strAction but we will see it later. So here : 300 is the X position 520 is the Y position 200,200 is supposed to be size of the element but it seems to not work with text 'font14' is the font, also 'font13' is available 0xFFFFFF00: so here it's the colour value and transparency coded in hexadecimal (from 00 to FF). so read this as 0xTTRRGGBB where T is the transparency value, R is red, G is green and as you guessed B is blue.

So now we add it to the previous code, and show it thanks to the A button of the pad

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7

class MyClass(xbmcgui.Window):

 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     self.strAction = xbmcgui.ControlLabel(300, 200, 200, 200, , 'font14', '0xFF00FF00')
     self.addControl(self.strAction)
     self.strAction.setLabel('Hello world')

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

Don't forget you have to push 'BACK' to stop the script !


You have to imagine the label as an element over the window and so we were able to add it but we can also remove it by using removeControl. We will use the B button to remove the label :

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7 ACTION_PARENT_DIR = 9

class MyClass(xbmcgui.Window):

 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     self.strAction = xbmcgui.ControlLabel(300, 200, 200, 200, , 'font14', '0xFF00FF00')
     self.addControl(self.strAction)
     self.strAction.setLabel('Hello world')
   if action == ACTION_PARENT_DIR:
     self.removeControl(self.strAction)

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

To add text there's also another feature called ControlFadeLabel which includes a reset function:

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit - A to reset text')
   self.strActionFade = xbmcgui.ControlFadeLabel(200, 300, 200, 200, 'font13', '0xFFFFFF00')
   self.addControl(self.strActionFade)
   self.strActionFade.addLabel('This is a fade label')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     self.strActionFade.reset()

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>


d) init parameters

When the class 'Myclass' is launched we can add elements that will run when the class is initialized. So here it's perfect to put some background image or some text that needs to be always on screen. So we add it in the init function:

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7 ACTION_PARENT_DIR = 9

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit, A to display text and B to erase it')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     self.strAction = xbmcgui.ControlLabel(300, 200, 200, 200, , 'font14', '0xFF00FF00')
     self.addControl(self.strAction)
     self.strAction.setLabel('Hello world')
   if action == ACTION_PARENT_DIR:
     self.removeControl(self.strAction)

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

We can also add a background image by including in the init function a ControlImage object:

<python>

 def __init__(self):
   self.addControl(xbmcgui.ControlImage(0,0,800,600, 'background.png'))
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit, A to display text and B to erase it')

</python>

Of course we display the image before the text :) When it's about path in directories, we always have to replace '\' by '\\' as '\' is reserved for special characters.


e) dialog box

What about a dialog box? So we will create function to add a message box :

<python>

 def message(self):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", " This is a nice message ")

</python>

And we will call it in another function using self.message()

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     self.message()
 def message(self):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", " This is a nice message ")

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

So now if you push 'A' a dialog will appear.

You can also use the message function in a more general way:

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.message('goodbye')
     self.close()
   if action == ACTION_SELECT_ITEM:
     self.message('you pushed A')
 def message(self, message):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", message)

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

So now you know how to call a function inside another function :) Be careful to only send strings in the message function, as to add integers and strings don't work at the same time without conversion!


There's also the very common yes / no dialog box :

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.goodbye()
 def goodbye(self):
   dialog = xbmcgui.Dialog()
   if dialog.yesno("message", "do you want to leave?"):
     self.close()

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>


f) buttons

Time to see how buttons work! We have tu use the function ControlButton. It takes 5 arguments. xbmcgui.ControlButton(350, 500, 80, 30, "HELLO") 350 is X postion, 500 is Y position, 80 the width, 30 is height and the last one is the text. First we have to create a button and to focus on it:

<python> self.button0 = xbmcgui.ControlButton(350, 500, 80, 30, "HELLO") self.addControl(self.button0) self.setFocus(self.button0) </python>

Then we have to define the action when the button is pushed:

<python> def onControl(self, control):

 if control == self.button0:
   print 'button pushed'

</python>

We can also remove the button of the screen using :

<python> self.removeControl(self.button0) </python>

As usual here is the code to see Python in action:

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
   self.button0 = xbmcgui.ControlButton(350, 500, 80, 30, "HELLO")
   self.addControl(self.button0)
   self.setFocus(self.button0)
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
 def onControl(self, control):
   if control == self.button0:
     self.message('you pushed the button')
 def message(self, message):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", message)

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>


We can also add more buttons, but so we have to define in which order they have to react. controlDown, controlUp, controlLeft and controlRight are here to do that. First we hav to create buttons then we have to link the direction between them.

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
   self.button0 = xbmcgui.ControlButton(250, 100, 80, 30, "HELLO")
   self.addControl(self.button0)
   self.button1 = xbmcgui.ControlButton(250, 200, 80, 30, "HELLO2")
   self.addControl(self.button1)
   self.button2 = xbmcgui.ControlButton(450, 200, 80, 30, "HELLO3")
   self.addControl(self.button2)
   self.setFocus(self.button0)
   self.button0.controlDown(self.button1)
   self.button1.controlUp(self.button0)
   self.button1.controlRight(self.button2)
   self.button2.controlLeft(self.button1)
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
 def onControl(self, control):
   if control == self.button0:
     self.message('you pushed the 1st button')
   if control == self.button1:
     self.message('you pushed the 2nd button')
   if control == self.button2:
     self.message('you pushed the 3rd button')
 def message(self, message):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", message)

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>


g) virtual keyboard

Some recent changes added the possibility to input text through a virtual keyboard.

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
   self.strActionInfo = xbmcgui.ControlLabel(100, 300, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   keyboard = xbmc.Keyboard('mytext')
   keyboard.doModal()
   if (keyboard.isConfirmed()):
     self.strActionInfo.setLabel(keyboard.getText())
   else:
     self.strActionInfo.setLabel('user canceled')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>


h) Lists

Since early april, we can add lists to XBMC Python. No need to tell more, so here is an example :

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(250, 80, 200, 200, , 'font14', '0xFFBBBBFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
   self.list = xbmcgui.ControlList(200, 150, 300, 400)
   self.addControl(self.list)
   self.list.addItem('Item 1')
   self.list.addItem('Item 2')
   self.list.addItem('Item 3')
   self.setFocus(self.list)
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
 
 def onControl(self, control):
   if control == self.list:
     item = self.list.getSelectedItem()
     self.message('You selected : ' + item.getLabel())  
 def message(self, message):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", message)

mydisplay = MyClass() mydisplay.doModal() del mydisplay </python>


i) Screen size

As XBMC can handle many different screen sizes, it's useful to get the values of the current one. So we wil see in action getHeight() and getWidth()

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
   screenx = self.getWidth()
   strscreenx = str(screenx)
   screeny = self.getHeight()
   strscreeny = str(screeny)
   self.strActionInfo = xbmcgui.ControlLabel(100, 200, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('screen width is ' + strscreenx)
   self.strActionInfo = xbmcgui.ControlLabel(100, 300, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('screen height is ' + strscreeny)
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>


j) Skin dir and localization

These infos can be useful for international scripts. getLocalizedString was added on april, 6th 2004. It reads infos from the xml language file. And here is an opportunity to introduce a new way to call a function : mydisplay.localinfos() The localinfos() function is called so you may think only infos of it would be displayed... But as the class MyClass as an init function, all datas from the init call are displayed first.

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(250, 80, 200, 200, , 'font14', '0xFFBBBBFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
 def localinfos(self):
   localtxt1 = xbmc.getLocalizedString(10000)
   localtxt2 = xbmc.getLocalizedString(10004)
   self.strActionInfo = xbmcgui.ControlLabel(100, 200, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Text using your xml language file : ' + localtxt1 + ' , ' + localtxt2 )    
   myskin = xbmc.getSkinDir()
   self.strActionInfo = xbmcgui.ControlLabel(100, 300, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Your skin dir is : /skin/' + myskin)

mydisplay = MyClass() mydisplay.localinfos() mydisplay .doModal() del mydisplay </python>


k) Language, IP address, DVD state, available memory and CPU temperature functions

These are my first attempt to add functions to the XBMC Python library and i'm proud enough of the result.

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(250, 60, 200, 200, , 'font14', '0xFFBBBBFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
 def localinfos(self):
   myinfos1 = xbmc.getLanguage()
   self.strActionInfo = xbmcgui.ControlLabel(100, 150, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Your language is : ' + myinfos1)
   myinfos2 = xbmc.getIPAddress()
   self.strActionInfo = xbmcgui.ControlLabel(100, 200, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Your IP adress is : ' + myinfos2)
   myinfos3 = xbmc.getDVDState()
   self.strActionInfo = xbmcgui.ControlLabel(100, 250, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   dvdstate = 
   if (myinfos3 == 1):
     dvdstate = 'DRIVE_NOT_READY'
   if (myinfos3 == 16):
     dvdstate = 'TRAY_OPEN'
   if (myinfos3 == 64):
     dvdstate = 'TRAY_CLOSED_NO_MEDIA'
   if (myinfos3 == 96):
     dvdstate = 'TRAY_CLOSED_MEDIA_PRESENT'            
   self.strActionInfo.setLabel('dvd state : ' + dvdstate )
   myinfos4 = xbmc.getFreeMem()
   self.strActionInfo = xbmcgui.ControlLabel(100, 300, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('free mem : ' + str(myinfos4) + ' Mb')
   myinfos5 = xbmc.getCpuTemp()
   self.strActionInfo = xbmcgui.ControlLabel(100, 350, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('cpu temp : ' + str(myinfos5) )

mydisplay = MyClass() mydisplay.localinfos() mydisplay .doModal() del mydisplay </python>

l) How to add a child window ?

It's always useful to add a child window when we don't have enough space on the main screen. So we will add another class that will be called when the button A is pressed.

<python> import xbmc, xbmcgui

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7

class MainClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(180, 60, 200, 200, , 'font14', '0xFFBBBBFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit - A to open another window')
   self.strActionInfo = xbmcgui.ControlLabel(240, 250, 200, 200, , 'font13', '0xFFFFFFFF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('This is the first window')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     popup = ChildClass()
     popup .doModal()
     del popup

class ChildClass(xbmcgui.Window):

 def __init__(self):
   self.addControl(xbmcgui.ControlImage(0,0,800,600, 'background.png'))
   self.strActionInfo = xbmcgui.ControlLabel(200, 60, 200, 200, , 'font14', '0xFFBBFFBB')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to return to the first window')
   self.strActionInfo = xbmcgui.ControlLabel(240, 200, 200, 200, , 'font13', '0xFFFFFF99')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('This is the child window')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()

mydisplay = MainClass() mydisplay .doModal() del mydisplay </python>


J) Unrelated XBMC functions

Here is an example on how to download a file through http. Try and Except are methods to test if things can be done, read the Python documentation for more infos.

<python> import xbmc, xbmcgui, urllib

  1. get actioncodes from keymap.xml

ACTION_PREVIOUS_MENU = 10 ACTION_SELECT_ITEM = 7

class MyClass(xbmcgui.Window):

 def __init__(self):
   self.strActionInfo = xbmcgui.ControlLabel(100, 120, 200, 200, , 'font13', '0xFFFF00FF')
   self.addControl(self.strActionInfo)
   self.strActionInfo.setLabel('Push BACK to quit - A to download')
 def onAction(self, action):
   if action == ACTION_PREVIOUS_MENU:
     self.close()
   if action == ACTION_SELECT_ITEM:
     webfile = 'http://www.google.com/images/logo.gif'
     localfile = 'Q:\\scripts\\logo.gif'
     self.downloadURL(webfile,localfile)
 def downloadURL(self,source, destination):        
   try:
     loc = urllib.URLopener()
     loc.retrieve(source, destination)
     self.message('download ok')
   except:
     self.message('download failed')
 def message(self, message):
   dialog = xbmcgui.Dialog()
   dialog.ok(" My message title", message)

mydisplay = MyClass() mydisplay .doModal() del mydisplay </python>

That's all for now, I hope this guide will help you to understand more the XBMC librairies on Python. More functions will be described in the next version of this tutorial.

Alex aka alx5962