• 1
  • 12
  • 13
  • 14(current)
  • 15
  • 16
  • 27
Release PyXBMCt: a Python framework for simple creating UI for XBMC addons
(2016-02-11, 16:06)Roman_V_M Wrote:
(2016-02-11, 12:23)Harvinder Wrote: Hi guys,

Im new to Python GUI with PYXBMCT, I've managed to created the layout with the buttons and images etc exactly where I want them to be etc. The part I'm stuck on is making the buttons do something.

Im using the self.connect(self.example_button, lambda: XXXXXXX) functions but not quite sure how to use it?

I have a horizontal navigation menu at the top and when you click the first button on the left I want it to display content such as image/button/info in the blank space below, I believe this is called multi-frame/window but how do I go about it?

If anybody could help me Id appreciate it allot.

Ive also looked at youtube tutorials for tkinter and tried to apply the method to pyxbmct but can't get it to work.

Thanks in Advance.

Have you read the documentation and examples for PyXBMCt? connect method accepts a function/method object that you want to execute if a Control is activated. lambda is used in special cases and you need to understand what you are doing.

With PyXBMCt you can emulate tabbed layout by creating sets of controls that are shown/hidden when a "tab" button is clicked, using their setVisible() methods.

Also, PyXBMCt is closer to PyQt as the name implies.

Hi Roman, thanks for the reply.

Yes I have viewed the startup guide and the documentation over at: http://romanvm.github.io/PyXBMCt/

I have created "Buttons" for the horizontal navigation at the top using "self.example_button = pyxbmct.Button('example')" refer to the image below:

EXAMPLE IMAGE

I will watch some tutorials on PyQt as see If I can get the buttons to work.

Thanks again.
Reply
(2016-02-11, 16:23)Harvinder Wrote: Hi Roman, thanks for the reply.

Yes I have viewed the startup guide and the documentation over at: http://romanvm.github.io/PyXBMCt/

I have created "Buttons" for the horizontal navigation at the top using "self.example_button = pyxbmct.Button('example')" refer to the image below:

EXAMPLE IMAGE

I will watch some tutorials on PyQt as see If I can get the buttons to work.

Thanks again.

PyQt tutorials will be overkill for your purpose, because PyQt is complex and developed for different purposes. Yes, PyXBMCt was influenced by PyQt, but they are not the same.

As for your scenario, as I said, you need to create sets of Controls (a set may include only one Control) that are displayed when you activate your "tabs".
Naturally, you need to connect your top buttons to function(s) that show/hide those sets of Controls by calling setVisible() method of each control.
Just to be clear: Controls may overlap and even be placed at the same spot, and by calling setVisible() of individual Controls you can show/hide them, e.g. show one Control and hide another. An invisible Control is not deleted, it still exists but is hidden and can be shown again.
Reply
(2016-02-11, 16:44)Roman_V_M Wrote:
(2016-02-11, 16:23)Harvinder Wrote: Hi Roman, thanks for the reply.

Yes I have viewed the startup guide and the documentation over at: http://romanvm.github.io/PyXBMCt/

I have created "Buttons" for the horizontal navigation at the top using "self.example_button = pyxbmct.Button('example')" refer to the image below:

EXAMPLE IMAGE

I will watch some tutorials on PyQt as see If I can get the buttons to work.

Thanks again.

PyQt tutorials will be overkill for your purpose, because PyQt is complex and developed for different purposes. Yes, PyXBMCt was influenced by PyQt, but they are not the same.

As for your scenario, as I said, you need to create sets of Controls (a set may include only one Control) that are displayed when you activate your "tabs".
Naturally, you need to connect your top buttons to function(s) that show/hide those sets of Controls by calling setVisible() method of each control.
Just to be clear: Controls may overlap and even be placed at the same spot, and by calling setVisible() of individual Controls you can show/hide them, e.g. show one Control and hide another. An invisible Control is not deleted, it still exists but is hidden and can be shown again.

Thanks, I've made some progress now. Im using the OOP method but having trouble with hiding controls using setVisible() method.

By setting the visibility in each of the tabs controls would make the code very repetitive so in order to try and make it efficient, I created a "def hide_controls()" and then listed all the controls that I would want to hide except the controls that make up the main navigation etc. However after calling in the "def hide_controls()" it doesn't display the controls that I want visible. Ive checked the error log and it says that the hide_control() isn't define globally?

I thought it would be easier to hide all the control I don't need to create a blank slate and then just re-enable the ones I wanted visible.

E.G Click a tab button > it HIDES all controls > I then enable controls I want visible.

Any ways to get around this? Or is there a different way of coding it to reduce repetition in the code.

Thanks again.
Reply
(2016-02-12, 02:46)Harvinder Wrote: By setting the visibility in each of the tabs controls would make the code very repetitive so in order to try and make it efficient, I created a "def hide_controls()" and then listed all the controls that I would want to hide except the controls that make up the main navigation etc. However after calling in the "def hide_controls()" it doesn't display the controls that I want visible. Ive checked the error log and it says that the hide_control() isn't define globally?

Probably that is because it isn't defined globally indeed. Scope and names visibility are fundamental things in Python, and you need to know this and LEGB rule if you want to get somewhere.

Quote:I thought it would be easier to hide all the control I don't need to create a blank slate and then just re-enable the ones I wanted visible.

E.G Click a tab button > it HIDES all controls > I then enable controls I want visible.

Any ways to get around this? Or is there a different way of coding it to reduce repetition in the code.

Thanks again.

You cannot avoid repetition because you have to call setVisible on each Control you want to show or hide. Unfortunately, there is no зythonic Group Control that would allow to control several items at once (technically, there is, but it does not work).
But I've suggested you to divide your Controls into sets or groups and control those groups individually, that is showing one group while hiding others, instead of working with all controls at once.

Or forget about PyXBMCt and try to create a skinned UI with xbmcgui.WindowXMLDialog. Skinned UIs are better suited for complex scenarios like yours.
Reply
@Roman_V_M
I wanted to ship PyXBMCt with my addon but it failed on my RPI. Taking a look at the code showed me that you don't define the _images path ideal.
It would be nice (for others) if you could change the code in addonwindow.py to use the following:

Code:
import os
import xbmc
import xbmcgui
#from xbmcaddon import Addon

#_images = os.path.join(Addon('script.module.pyxbmct').getAddonInfo('path'), 'lib', 'pyxbmct', 'textures', 'default')
_images = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'textures', 'default')

In my opinion this will work in all cases.
Reply
(2016-03-01, 13:51)tim619 Wrote: @Roman_V_M
I wanted to ship PyXBMCt with my addon but it failed on my RPI. Taking a look at the code showed me that you don't define the _images path ideal.
It would be nice (for others) if you could change the code in addonwindow.py to use the following:

Code:
import os
import xbmc
import xbmcgui
#from xbmcaddon import Addon

#_images = os.path.join(Addon('script.module.pyxbmct').getAddonInfo('path'), 'lib', 'pyxbmct', 'textures', 'default')
_images = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'textures', 'default')

In my opinion this will work in all cases.

As to my knowledge, a Kodi Python addon must query its actual path only via .getAddonInfo('path'), and not by other ways. That is why PyXBMCt module addon (that is included in the official Kodi addon repo, BTW) builds the path to its texture files this way.

But if you don't want to rely on the Kodi official repo and want to include PyXBMCt into your addon for some reasons, you can change the code as you like. It's GPL, after all. Smile
Reply
I have updated the demo addon: a TextBox control now implements auto-scrolling of a long text, and an Image control has a new picture - an old XBMC logo was replaced with Big Buck Bunny.

I also plan to start implementing a new design based on visual elements from the new Estuary skin that will become the default one in Kodi 17 Krypton. However, I'm not sure how to set visual appearance of PyXBMCt controls. There are several options:

- Switch to the Estuary design completely and remove the old Confluence textures.
- Implement version check and set the visual appearance based in Kodi version. That is, to use the old design for versions < 17 and the new one for versions >= 17.
- Add some kind of switch that would allow to control the visual appearance programmatically.

What do you think?
Reply
BTW, is there any way to see what image files are currently loaded in the Kodi UI? For example, I open a Yes/No dialog and want to see what texture images have been loaded to visualize this dialog? I need this to find necessary image files in skin resources.
Reply
This is a public beta of the new theme for PyXBMCt based on the new default Kodi skin -- Estuary.

Download link: https://yadi.sk/d/a7H_TTyJpzwNZ

Screenshot:

Image

Instructions:

Download the ZIP from the download link and install it via Kodi addon manager. The new version is fully compatible with existing code, so you don't need to make any changes.
To disable the new Estuary theme you need to change the skin module-level property before defining your GUI elements. For example:

PHP Code:
import pyxbmct

pyxbmct
.skin.estuary False 

Any comments and suggestions are welcomed. Please take into account that I'm very bad with imaging software, so my abilities to improve the look of PyXBMCt are limited. I will gladly accept any help in this matter, with proper crediting, of course.
Reply
Hi Roman. This looks like awesome work you've done on this library! I've decided to start using it for an add-on I'm going to make. Couple of questions for you though.

I'm wanting to make a TV guide add-on for IPTV links that utilise both live and catchup sources. So I was wondering if a GUI such as iVue or FTV Guide was achievable using your library? I can see that theres lists but only one dimensional. I'm looking for a way to populate a grid/table with varying cell width.

If this isn't possible, my other solution was to have two separate lists. One with a list of TV channels and the other (which gets updated depending on the channel selected) a list of programs. For this to work well, i was wondering if there was a way to stipulate a default/starting list item? Say you had a list of 10 items, would it be possible to automatically select item 5, then the user be able to scroll up/down from that position?

Any help/information would be appreciated.
Thanks!
Reply
I'm not familiar with the software you have mentioned, but it seems that PyXBMCt is not a good choice for your requirements. I think you should consider a skinned XML-based UI.
Reply
Okay. Thanks for your prompt reply. I'll look in to it. I'm not too great with gui's which is why I was glad when I saw your library. But I'll look into it. Cheers
Reply
I'm a bit stumped on how I can get the connect to work.
Currently I have 9 buttons displaying on the screen and have set navigation between all of them, the idea is that each one is linked to a camera, select button 1 and it will show the video for camera 1, select button 2 and it play camera 2.

I'm storing the buttons in an array and the using the connect like below;

Code:
for i in range(0, 9):
    self.camera[i] = pyxbmct.Button("Camera "+str(i), noFocusTexture=buttonBlur, focusTexture=buttonFocus, font='font14')
    self.placeControl(self.camera[i], 2, column+i, 1, 20)
    self.connect(self.camera[i], lambda: self._play_camera(i))

Now when this plays this always plays the last camera instead of 'i' I'm guessing i may need to read up on exactly how lambda actually works as I'm guessing this is pulling i outside of the for loop when selected, rather than assigning it at the point the connect is created?

Just wondered if someone could lend a hand on the best way to get this working?
Reply
2 ptom

lambda defers your self._play_camera method execution until the moment of the actual call when a button is activated, meaning that i variable is passed not at the moment of lambda creation but at the moment of lambda execution. You nee to somehow get you button id when actual call to self._play_camera takes place.

UPD: Try to use a factory function that will create your callables. Something like that:

Code:
def play_camera_factory(i):
    """Create play_camera callable"""
    def play_camera():
        """
        Do something with a camera using
        a current i value
        """
        ...

    return play_camera

...
for i in range(0, 9):
    ...
    self.connect(self.camera[i], play_camera_factory(i))
Reply
that works great!!! thanks so much Roman!

one other thing i was going to ask as well is there a way to tie functions into a hover over a button? having a look around and can't see anything that would allow this
Reply
  • 1
  • 12
  • 13
  • 14(current)
  • 15
  • 16
  • 27

Logout Mark Read Team Forum Stats Members Help
PyXBMCt: a Python framework for simple creating UI for XBMC addons4