Share variables between windows
#1
Hi,

I have 2 xbmcgui.WindowXML. The first one is for login (user and password) and the second one is to show the a list retrieved from the server. The first one creates an object with the name and the id of the user. I want to share this object within windows. How can I do that?

Thanks in advance
Reply
#2
hi there,

I publish my own response if anyone is interested.

I have worked in four ways:

1.- global variables
2.- passing parameters between instances of classes (xbmcgui.WindowXML)
3.- saving data in a sqlite database
4.- file serialization with cPickle

1.- Apparently it is not possible because the windows are constantly recharged. If someone says the opposite, please tell me how. On the other hand as I read in forums, global variables and singleton are not a good idea. KO.
2.- It is the classic way, but if we want to modify the objects passed as parameters and return them to the parent window, I do not see how. I have released another question on the forum on how the call stack window works, but nobody gave me answer. KO
3.- Complicated because a database requires that the recorded data are structured. We may record a json serialized class in a text field and put a primary key as identifier. Even we could put a timestamp field to use as timeout data validity. OK, but I think the access time and reading, will be superior to a solution based on flat files.
4.- I tried with cPickle and seems interesting as quick and effective solution. Using script.module.t0mm0.common (https://github.com/Eldorados/script.module.t0mm0.common) functions (load_data and save_data) make it possible to save and load information in both ways between windows. I see an evolution of this concept in http://wiki.xbmc.org/index.php?title=HOW...ce_Scripts developed by Alexpoet and based on sockets but I think that share variables between windows of the same addon is enough with cPickle.OK.

For me, the winner is cPickle (4).

Do you think the same? Any other suggestions?

Best regards
Reply
#3
So if I have this straight, your main script is calling up a couple of different wiindows, and you want the information from one window to show up for the other?

Why not create the object in the main script, and pass that to each of the windows?

In this example, ball is the object you want to share, class a & b are like your windows, and class c is like your Main class:

Code:
class ball:
    def __init__(self):
        self.kick = "a"

class a:
    def __init__(self, var):
        self.var = var

class b:
    def __init__(self,var):
        self.var = var

class c:
    def __init__(self, var):
        self.var = ball()
        self.a = a(self.var)
        self.b = b(self.var)

From IDLE;
>>> cc.var.kick
'a'
>>> cc.a.var.kick
'a'
>>> cc.b.var.kick
'a'

Now change the value of kick:
cc.var.kick = "b"


And the value of cc.a.var.kick and cc.b.var.kick will also change.
>>> cc.var.kick
'b'
>>> cc.a.var.kick
'b'
>>> cc.b.var.kick
'b'
Reply
#4
Hi Karnagious,

Thanks for your answer, it was very enlightening. In fact my question was a little more complex (not much) but your answer has been very helpful.

The idea based on your ball's example was a window cascade call (default object c -> calls a -> a calls b:

Code:
class ball(object):
    def __init__(self):
        self.kick = "a"

class a(object):
    def __init__(self, var):
        self.var = var
        self.b = b(self.var)

class b(object):
    def __init__(self,var):
        self.var = var

class c(object):
    def __init__(self,var):
        self.var = var
        self.a = a(self.var)
        

the_ball = ball()
the_c = c(the_ball)
print(the_c.var.kick)
print(the_c.a.var.kick)
print(the_c.a.b.var.kick)

the_c.var.kick = "b"

print(the_c.var.kick)
print(the_c.a.var.kick)
print(the_c.a.b.var.kick)

the_c.a.var.kick = "c"

print(the_c.var.kick)
print(the_c.a.var.kick)
print(the_c.a.b.var.kick)

the_c.a.b.var.kick = "d"

print(the_c.var.kick)
print(the_c.a.var.kick)
print(the_c.a.b.var.kick)

Taking this as a base I modify my addon.

In the default.py of the addon I create the global object (ball)


Code:
SessionDataGlobal = CSession()

I create the first Window and add the param SESSION with the global object
Code:
import resources.lib.Screen1 as Screen
    ui = Screen.Screen1 ('Screen1 .xml', AddonPath, 'default', SESSION=SessionDataGlobal)
    ui.doModal()
    del ui

in the first window I receive the param:
Code:
class Screen1 (xbmcgui.WindowXML):
    def __init__(self, *args, **kwargs):
        xbmcgui.WindowXML.__init__(self, *args, **kwargs)

        self.SessionDataG = kwargs["SESSION"]

I do the same when I call the second screen from the first screen:

Code:
import resources.lib.Screen2 as Screen
        ui = Screen.Screen2 ('Screen2.xml', addon.get_path(), 'default', SESSION=self.SessionDataG)
        ui.doModal()
        del ui

The difference is that the object is local (self.SessionDataG). And finally in the Screen2 I recover the object like Screen1.

I can modify the object at any level because it's passed by reference so when a Screen2 is closed the modified data passes to Screen 1 and so on.

So the option 2 is OK too.

Thanks for your help
Reply

Logout Mark Read Team Forum Stats Members Help
Share variables between windows0