How to handle Events in another Python Script using PyCEGUI

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

pizzazhang
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Apr 13, 2011 14:54
Location: Shanghai/China

How to handle Events in another Python Script using PyCEGUI

Postby pizzazhang » Wed Apr 13, 2011 15:28

Hi, everybody:
I'm new to python but I try to do something using PyOgre and PyCEGUI. My problem is: I want to put the window events handler in another python script file, just like using lua script when I use C++ CEGUI. Here is what I do to implement :
in my demo.py:

Code: Select all

    def _createScene(self):
        mygui = MYGUI.getSingleton()
        execfile('gui_logic.py')

the first line in this function I just setup CEGUI and set resource location etc.
then I execute a python file using execfile

in my events handler file -- gui_logic.py:

Code: Select all

class GuiLogic:
    def btn_clicked(self, args):
        button = MYGUI.getSingleton().getWindow("Root/BgImg/QuitBtn")
        button.setText("HAHA")
        return True

    def subscribe(self):
        MYGUI.getSingleton().loadWindow("Root")
        button = MYGUI.getSingleton().getWindow("Root/BgImg/QuitBtn")
        button.subscribeEvent(CEGUI.PushButton.EventClicked,
                              self,
                              "btn_clicked")


if __name__=='__main__':
    GuiLogic().subscribe()


I don't want to be implement these in a class but the subscribeEvent function takes
three arguments so... anyway when I launch the demo, it successfully load the layoutfile

Code: Select all

13/04/2011 23:07:37 (Std)    ---- Successfully completed loading of GUI layout from 'Root.layout' ----
which I checked in log file.
Here is my problem: when I clicked the button, the program crashed! I don't know why because the log files and Eclipse(I use Eclipse and PyDev) give me no error track information!
So I really want to know how to handler CEGUI window events in another python script file just like lua does! I can easily use tolua++ handle a big part of my Class function in a lua script but now in Python I really don't know how to do.

Any advice will be appreciated!
Last edited by pizzazhang on Thu Apr 14, 2011 05:21, edited 1 time in total.

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: How to handler Events in another Python Script using PyC

Postby Kulik » Wed Apr 13, 2011 15:39

It's because you aren't referencing GuiLogic class in python at any place, it gets garbage collected and boom! This is one of the dangers of C++ and Python interactions. I think I may be able to somehow solve this my increasing refcount of given instance when subscribing but it would probably slow things down a bit, I will consider it though.

Always make sure that what you pass to CEGUI is referenced in your python code somewhere (it's refcount doesn't drop to 0)

pizzazhang
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Apr 13, 2011 14:54
Location: Shanghai/China

Re: How to handler Events in another Python Script using PyC

Postby pizzazhang » Thu Apr 14, 2011 04:45

Kulik wrote:It's because you aren't referencing GuiLogic class in python at any place, it gets garbage collected and boom! This is one of the dangers of C++ and Python interactions. I think I may be able to somehow solve this my increasing refcount of given instance when subscribing but it would probably slow things down a bit, I will consider it though.

Always make sure that what you pass to CEGUI is referenced in your python code somewhere (it's refcount doesn't drop to 0)


Thank you first for your reply. Now I changed my code in this way :

Code: Select all

class GuiLogic:
    def btn_clicked(self, args):
        button = CEGUI.WindowManager.getSingleton().getWindow("Root/BgImg/QuitBtn")
        button.setText("HAHA")
        return True

    def subscribe(self):
        sheet = CEGUI.WindowManager.getSingleton().loadWindowLayout("Root.layout")
        CEGUI.System.getSingleton().setGUISheet(sheet)
        button = CEGUI.WindowManager.getSingleton().getWindow("Root/BgImg/QuitBtn")
        button.subscribeEvent(CEGUI.PushButton.EventClicked,
                              self,
                              "btn_clicked")

I removed MyGUISystem(I put CEGUI handlers in this class but I think my problems comes here) in gui_logic.py.
Also I didn't put main in gui_logic.py but I call GuiLogic's function subscribe in createScene in demo.py:

Code: Select all

    def _createScene(self):
        MYGUI.getSingleton()
        GuiLogic().subscribe()

everything seems working but when I clicked the button, I got

Code: Select all

AttributeError: 'tuple' object has no attribute 'btn_clicked'

I think the error comes in subscribeEvent(param1, param2, param3)
if I put this function in demo.py it just works perfect but in another class...I got confused.
I looked into the cegui demos that py-ogre has and I didn't find any samples that putting gui logic in another python file. So if someone gives such a sample I will really really appreciate his/her work!

pizzazhang
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Apr 13, 2011 14:54
Location: Shanghai/China

Re: How to handle Events in another Python Script using PyCE

Postby pizzazhang » Thu Apr 14, 2011 14:04

Finally I solved it. I'm new to Python so I know little about Python's garbage collection as Kulik mentioned.
In C++ we used to clean the resource by ourselves but in Python it is automatic. I read Kulik's advice again and
search some python knowledge, finally just a little change and my program works right:
in demo.py:

Code: Select all

        self.logic = gui_logic.GuiLogic()
        self.logic.subscribe()

use self.logic to store the ref to GuiLogic instance so that Python won't immediately clean up the reference.

But it's still not convenient for me because in C++ I just execute a lua script file in my code and not instance a class(handle all events in lua, and function subscibe() in lua only takes a Event name and a function name as arguments), but in Python now I must instance a class in code and write event handlers in a class because function subscribe() must take a Class ref argument in the second place.
I know not everything is perfect so I shouldn't blame too much on Python. Also I shouldn't compare between Python and lua since they apply in a different area. I like Python so I should get used to the Python Way which is very different to C++ :D

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: How to handle Events in another Python Script using PyCE

Postby Kulik » Thu Apr 14, 2011 15:19

You can subscribe to free functions but I have no idea how python deals with them, if the same pitfalls apply.

subscribeEvent("EventName", someFreeFunction) should work too

pizzazhang
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Apr 13, 2011 14:54
Location: Shanghai/China

Re: How to handle Events in another Python Script using PyCE

Postby pizzazhang » Thu Apr 14, 2011 16:57

Code: Select all

import ogre.gui.CEGUI as CEGUI

       
def btn_clicked(args):
    button = CEGUI.WindowManager.getSingleton().getWindow("Root/BgImg/QuitBtn")
    button.setText("HAHA")
    return True

def subscribe():
    sheet = CEGUI.WindowManager.getSingleton().loadWindowLayout("Root.layout")
    CEGUI.System.getSingleton().setGUISheet(sheet)
    button = CEGUI.WindowManager.getSingleton().getWindow("Root/BgImg/QuitBtn")
    button.subscribeEvent("Clicked",
                          btn_clicked)

if __name__ == '__main__':
    subscribe()

I got this:

Code: Select all

  File "gui_logic.py", line 23, in <module>
    subscribe()
  File "gui_logic.py", line 20, in subscribe
    btn_clicked)
NameError: global name 'btn_clicked' is not defined


If I change btn_clicked to string like in lua, I got this:

Code: Select all

  File "gui_logic.py", line 20, in subscribe
    "btn_clicked")
Boost.Python.ArgumentError: Python argument types in
    EventSet.subscribeEvent(PushButton, str, str)
did not match C++ signature:
    subscribeEvent(class CEGUI::Tree *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::EventSet *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::System *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::MouseCursor *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Window *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::MultiColumnList *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::DragContainer *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::RadioButton *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Spinner *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Slider *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Thumb *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Editbox *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::FrameWindow *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::GUISheet *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Scrollbar *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Checkbox *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Combobox *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Listbox *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::Titlebar *, class CEGUI::String, struct _object *, class CEGUI::String)
    subscribeEvent(class CEGUI::PushButton *, class CEGUI::String, struct _object *, class CEGUI::String)

it seems in Python I only can use function subscribeEvent() with 3 arguments, but in C++, yes, what you mentioned works well.

User avatar
dermont
Quite a regular
Quite a regular
Posts: 75
Joined: Mon Aug 29, 2005 16:15

Re: How to handle Events in another Python Script using PyCE

Postby dermont » Fri Apr 15, 2011 07:23

pizzazhang wrote:it seems in Python I only can use function subscribeEvent() with 3 arguments, but in C++, yes, what you mentioned works well.


For python-ogre the SubscribeEvent format is explained here:
http://www.ogre3d.org/addonforums/viewt ... ent#p15968

Code: Select all

    .subscribeEvent(CEGUI.PushButton.EventClicked, self, "handleQuit")
    .subscribeEvent(CEGUI.PushButton.EventClicked, freefunction, "")


For example from Demo_CEGUI_Gui_2.py:

Code: Select all

eb.subscribeEvent(CEGUI.Window.EventTextChanged, textChangedHandler,"")


pizzazhang wrote:I looked into the cegui demos that py-ogre has and I didn't find any samples that putting gui logic in another python file. So if someone gives such a sample I will really really appreciate his/her work!


Try the following link I think that is what you are looking for:
http://groups.google.com/group/python-o ... t&q=cegui#

pizzazhang
Not too shy to talk
Not too shy to talk
Posts: 23
Joined: Wed Apr 13, 2011 14:54
Location: Shanghai/China

Re: How to handle Events in another Python Script using PyCE

Postby pizzazhang » Fri Apr 15, 2011 10:05

For example from Demo_CEGUI_Gui_2.py:

Code: Select all

eb.subscribeEvent(CEGUI.Window.EventTextChanged, textChangedHandler,"")

'dermont':
Fixed. Tank you very very much. Yeah, I just missed such thing in cegui demos. I should check the sample code more carefully next time! Really appreciate your help!

User avatar
Kulik
CEGUI Team
Posts: 1382
Joined: Mon Jul 26, 2010 18:47
Location: Czech Republic
Contact:

Re: How to handle Events in another Python Script using PyCE

Postby Kulik » Fri Apr 15, 2011 13:34

Yeah, it would be great if someone added these to the wiki.

Jamarr
CEGUI MVP
CEGUI MVP
Posts: 812
Joined: Tue Jun 03, 2008 23:59
Location: USA

Re: How to handle Events in another Python Script using PyCE

Postby Jamarr » Fri Apr 15, 2011 15:59

It would also be great if new users stop posting their "usage" questions in the "chit-chat and off-topic" forum so I would not have to move them into the "beginners help" forum every other day. :hammer:
If somebody helps you by replying to your thread, upvote him/her as a thanks! Make sure to include your CEGUI.log and everything you tried when posting! And remember that we are not magicians!


Return to “Help”

Who is online

Users browsing this forum: No registered users and 31 guests