Problems with Python, MMS and inheritance

Discussion about user contributed plugins

Moderator: Moderator

Tommie
Posts: 24
Joined: Sun Jan 20, 2008 4:52 pm
Contact:

Problems with Python, MMS and inheritance

Postby Tommie » Sun Jul 06, 2008 7:36 pm

As I am continuing my work on my rtorrent pyglet, I observed some strange issues about the python plugin.

For example, I wanted to create a Window by deriving it from the generic window class and adding a new constructor that employs the path to the xml file:

Code: Select all

class MyWindow(mmsv2gui.Window):
    def __init__(self):
        # call the original constructor method
        mmsv2gui.Window.__init__(self, "gui/mywindow.xml")
        # and now we do some interesting stuff

win = MyWindow()
win.doModal()

That code does not work like I suppose it should. The inherited __init__ method does not do anything.

I observed a similar thing when overloading the close()-method of a window:

Code: Select all

  def close(self):
      # some cleanup code
      self.foo = None
      mmsv2gui.Window.close(self)


The overloaded method gets executed, however the window does not close.

Any idea about those issues?

Fredde
veteran
Posts: 288
Joined: Tue Dec 06, 2005 7:18 am
Location: Sweden

Re: Problems with Python, MMS and inheritance

Postby Fredde » Tue Jul 08, 2008 12:25 pm

Tommie wrote:As I am continuing my work on my rtorrent pyglet, I observed some strange issues about the python plugin.

For example, I wanted to create a Window by deriving it from the generic window class and adding a new constructor that employs the path to the xml file:

Code: Select all

class MyWindow(mmsv2gui.Window):
    def __init__(self):
        # call the original constructor method
        mmsv2gui.Window.__init__(self, "gui/mywindow.xml")
        # and now we do some interesting stuff

win = MyWindow()
win.doModal()

That code does not work like I suppose it should. The inherited __init__ method does not do anything.

The above behaviour is beacuse I didn't add the tp_init (initialization function) function in the C-code, I only implemented the tp_new function (constructor). But there is still a way to load a xml-file and have a __init__ method like above.

Code: Select all

class MyWindow(mmsv2gui.Window):
    def __init__(self, xmlpath):
        # and now we do some interesting stuff

win = MyWindow("gui/mywindow.xml")
win.doModal()

Because the tp_init method isn't implemented in C-code you have to pass the xml-file path to the constructor (tp_new).

Tommie wrote:I observed a similar thing when overloading the close()-method of a window:

Code: Select all

  def close(self):
      # some cleanup code
      self.foo = None
      mmsv2gui.Window.close(self)

The overloaded method gets executed, however the window does not close.

Any idea about those issues?

Hmm, the above code should work, but I'am not sure why. Have to do some testing myself.

Tommie
Posts: 24
Joined: Sun Jan 20, 2008 4:52 pm
Contact:

Re: Problems with Python, MMS and inheritance

Postby Tommie » Tue Jul 08, 2008 5:02 pm

Fredde wrote:
Tommie wrote:That code does not work like I suppose it should. The inherited __init__ method does not do anything.

The above behaviour is beacuse I didn't add the tp_init (initialization function) function in the C-code, I only implemented the tp_new function (constructor). But there is still a way to load a xml-file and have a __init__ method like above.

So how do I do real inheritance with constructor chaining?

Fredde
veteran
Posts: 288
Joined: Tue Dec 06, 2005 7:18 am
Location: Sweden

Re: Problems with Python, MMS and inheritance

Postby Fredde » Tue Jul 08, 2008 7:23 pm

Tommie wrote:So how do I do real inheritance with constructor chaining?

Sadly to say it's not possible the way it is right now. I now see the error of my way :? The same goes for all the other controls like button, label, ... if you would like to inherit from them.

I'am a way until the end of this week, but I will after that add the init function i C-code to support propper constuctor chaining. Thx Tommie.

Tommie
Posts: 24
Joined: Sun Jan 20, 2008 4:52 pm
Contact:

Postby Tommie » Tue Jul 08, 2008 8:02 pm

When you are at it, consider changing ListItem; It would be great if the List widget would use the getLabel and getLabel2 methods to access the text stored - I'd really like to overload the method for some more dynamic list items.

Fredde
veteran
Posts: 288
Joined: Tue Dec 06, 2005 7:18 am
Location: Sweden

Postby Fredde » Fri Jul 11, 2008 7:40 pm

Finally done with the update to support proper constructor chaining. I have not committed the code yet, because I need to update the docs first.

I need to issue a warning to all python developers. This update will probably break scripts written until now. It's not an major issue, not much need to be changed. The changes are related to inheritance (see code below)

Code: Select all

class MyWindow(mmsv2gui.Window):
  def __init__(self):
    mmsv2gui.Window.__init__(self)
    ...

It's the last line that need to be added to ensure that the base class is properly initialized. Without that call a AssertionError exception is thrown.

The same goes for all controls (if you would like to inherit from them)

Code: Select all

class MyButton(mmsv2gui.ButtonControl):
  def __init__(self, x, y, w, h, text, ...):
    mmsv2gui.ButtonControl.__init__(self, x, y, w, h, text, ...)
    ...

I will document this in the tutorial part of the python plugin documentation.

I'am sorry for the inconvenience, but this is the proper way to do it, as Tommie stated.

Tommie wrote:When you are at it, consider changing ListItem; It would be great if the List widget would use the getLabel and getLabel2 methods to access the text stored - I'd really like to overload the method for some more dynamic list items.

I'am not really sure what you mean here, especially with the statement "It would be great if the List widget would use the getLabel and getLabel2 methods to access the text stored".

Tommie
Posts: 24
Joined: Sun Jan 20, 2008 4:52 pm
Contact:

Postby Tommie » Sat Jul 12, 2008 1:15 pm

Fredde wrote:
Tommie wrote:When you are at it, consider changing ListItem; It would be great if the List widget would use the getLabel and getLabel2 methods to access the text stored - I'd really like to overload the method for some more dynamic list items.

I'am not really sure what you mean here, especially with the statement "It would be great if the List widget would use the getLabel and getLabel2 methods to access the text stored".


Sure. While developing torrent-inspector, I derived a class from ListItem. Instead of using setLabel/setLabel2, I tried to overload the getLabel/getLabel methods, hoping that the List-Widget uses them to retrieve the label data. I wanted to pull the labels from an external source instead of storing them in the object (think of model-view-controll):

Code: Select all

class MyItem(ListItem):
  def getLabel(self):
    return "foobar"


But it seems that the list widget does not use the methods. Changing that would allow much cleaner implementations of Lists in MMS. Check the J2SE documentation about the ListModel classes for more information, Java is even going further.

Fredde
veteran
Posts: 288
Joined: Tue Dec 06, 2005 7:18 am
Location: Sweden

Postby Fredde » Sat Jul 12, 2008 8:05 pm

Tommie wrote:Sure. While developing torrent-inspector, I derived a class from ListItem. Instead of using setLabel/setLabel2, I tried to overload the getLabel/getLabel methods, hoping that the List-Widget uses them to retrieve the label data. I wanted to pull the labels from an external source instead of storing them in the object (think of model-view-controll):

Code: Select all

class MyItem(ListItem):
  def getLabel(self):
    return "foobar"


But it seems that the list widget does not use the methods. Changing that would allow much cleaner implementations of Lists in MMS. Check the J2SE documentation about the ListModel classes for more information, Java is even going further.

I see your point. Let me explain how I implemented this. Every python class in the plugin "wraps" a corresponding C++ class, so when a window is rendering its controls it's the methods of the wrapped C++ classes that is being called. In your case you overload a method from a python class which have no effect in the rendering code, as explained above. Your idea would have worked if you coded in C++.

My implementation of the list control does not separate the model from the view (as the Java JList does). It would be possible to redesign the C++ list item class to have a reference to its python wrapper, that way it's possible to call python methods from C++ code, but I think this way is like thinking two wrongs make it right. It would be better to redesign the list control to separate the model from the view.

Fredde
veteran
Posts: 288
Joined: Tue Dec 06, 2005 7:18 am
Location: Sweden

Postby Fredde » Sun Jul 13, 2008 12:14 pm

I have committed the changes mention in previous post. I have also updated the appletrailer/youtube scripts to support changes.


Return to “user plugins”

Who is online

Users browsing this forum: No registered users and 1 guest