wxGlade and Events. HOW?!

I'm messing around with wxGlade for some instant gratification, but I simply
can't figure out how to add events to my app. For instance, I'd like to add a
simple menu-event to gracefully close down the app, but no matter where I put
the EVT_MENU, the interpreter bitches about an invalid syntax. No matter what I
do to correct the syntax, I get the same error message. I've tried to put in in
__set_properties() and __do_layout(), but nothing helped.

Score some karma and help out a newbie, will ya'?!

···

#-------------------------------------------------------------
#!/usr/bin/env python
# generated by wxGlade 0.2.1 on Tue Apr 15 13:17:17 2003
from wxPython.wx import *

class MyFrame(wxFrame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wxDEFAULT_FRAME_STYLE
        wxFrame.__init__(self, *args, **kwds)
        
        # Menu Bar
        self.frame_1_menubar = wxMenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wxMenu()
        wxglade_tmp_menu.Append(ID_EXIT, "Exit", "Blow This Popstand!")
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")

    # This is the problem generating an invalid syntax. WHY?!
    EVT_MENU(self, ID_EXIT, self.OnExit)
        # Menu Bar end

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

  def OnExit(self, event):
    self.Close(true)

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame_1")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wxBoxSizer(wxVERTICAL)
        self.SetAutoLayout(1)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        sizer_1.SetSizeHints(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame
--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

Fixed for a newbie, and karma now owes me.

Problems:
    Python works on indentation levels. Don't screw them up - you lose class definitions etc.
    ID_EXIT wasn't defined anywhere.

Less ugly fix:
    wxGlade is great for GUI design. Do your GUI magic in another file that imports and uses MyFrame. Then if you need to do GUI reworking, you don't lose your GUI magic. wxGlade is pretty good at taking care of your code vs its code, but I don't trust anyone else not to overwrite my code.
    
Hope this helps,

Chris.

···

#-------------------------------------------------------------
#!/usr/bin/env python
# generated by wxGlade 0.2.1 on Tue Apr 15 13:17:17 2003
from wxPython.wx import *

ID_EXIT = wxNewId()

class MyFrame(wxFrame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wxDEFAULT_FRAME_STYLE
        wxFrame.__init__(self, *args, **kwds)

        # Menu Bar
        self.frame_1_menubar = wxMenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wxMenu()
        wxglade_tmp_menu.Append(ID_EXIT, "Exit", "Blow This Popstand!")
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")

        # This is the problem generating an invalid syntax. WHY?!
        EVT_MENU(self, ID_EXIT, self.OnExit)
        # Menu Bar end

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

    def OnExit(self, event):
        self.Close(true)

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame_1")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wxBoxSizer(wxVERTICAL)
        self.SetAutoLayout(1)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        sizer_1.SetSizeHints(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame

class DemoApp(wxApp):
    def OnInit(self):
        frame = MyFrame(None, -1, "Test Frame")
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = DemoApp(0)
    app.MainLoop()

if __name__ == '__main__':
    main()

----- Original Message -----
From: Eladio Ventura
To: wxPython
Sent: Tuesday, April 15, 2003 10:53 PM
Subject: [wxPython-users] wxGlade and Events. HOW?!

I'm messing around with wxGlade for some instant gratification, but I simply
can't figure out how to add events to my app. For instance, I'd like to add a
simple menu-event to gracefully close down the app, but no matter where I put
the EVT_MENU, the interpreter bitches about an invalid syntax. No matter what I
do to correct the syntax, I get the same error message. I've tried to put in in
__set_properties() and __do_layout(), but nothing helped.

Score some karma and help out a newbie, will ya'?!

#-------------------------------------------------------------
#!/usr/bin/env python
# generated by wxGlade 0.2.1 on Tue Apr 15 13:17:17 2003
from wxPython.wx import *

class MyFrame(wxFrame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wxDEFAULT_FRAME_STYLE
        wxFrame.__init__(self, *args, **kwds)
        
        # Menu Bar
        self.frame_1_menubar = wxMenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wxMenu()
        wxglade_tmp_menu.Append(ID_EXIT, "Exit", "Blow This Popstand!")
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")

# This is the problem generating an invalid syntax. WHY?!
EVT_MENU(self, ID_EXIT, self.OnExit)
        # Menu Bar end

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

def OnExit(self, event):
self.Close(true)

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame_1")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wxBoxSizer(wxVERTICAL)
        self.SetAutoLayout(1)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        sizer_1.SetSizeHints(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame
--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

* Chris Munchenberg <cjm@ava.com.au> [030415 21:40]:

Fixed for a newbie, and karma now owes me.

Sure does, ha ha! Wow, I can't believe how helpful the people on this
list have been so far. You guys are amazing!

Problems:
    Python works on indentation levels. Don't screw them up - you lose class definitions etc.
    ID_EXIT wasn't defined anywhere.

I was just throwing up a quick sample to illustrate the problem and
ID_EXIT got munged out of the example in process. *sigh* Sorry about
that. Oh well, making mistakes is what being a newbie is all about...

Less ugly fix:
wxGlade is great for GUI design. Do your GUI magic in another file that
imports and uses MyFrame. Then if you need to do GUI reworking, you don't
lose your GUI magic. wxGlade is pretty good at taking care of your code vs
its code, but I don't trust anyone else not to overwrite my code.

That sounds like a fabulous idea, but I'm scratching my head to a
polished chromedome trying to wrap my peabrain around it. So you would
keep the wxGlade generated code in say, MyGUI.py and the functions the
GUI is supposed to execute in say MyAPP.py? Then instantiate MyFrame
in MyAPP.py or somesuch like in your DemoApp class? The events would
still go into MyGUI I take it, but where would OnExit() go? If all the
functions go into into MyGUI.py anyway, then what's the point?

I would simply KILL for an example of this scheme. Any ideas? Or maybe I
should wait until I have gleaned through demo.py.

Hope this helps,

Sure did - thanks for taking the time to respond so promptly! It works
beautifully, man.

···

--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

Hi all,

I am trying to use the right-aligned text control that was kindly
contributed by Josu Oyanguren in one the earlier demos. It is a subclass of
wxTextCtrl that traps an EVT_PAINT event, and then does the following -

def OnPaint(self, event):
    dc = wxPaintDC(self)
    dc.SetFont(self.GetFont())
    dc.Clear()
    text = self.GetValue()
    textwidth, textheight = dc.GetTextExtent(text)
    dcwidth, dcheight = self.GetClientSizeTuple()

    y = (dcheight - textheight) / 2
    x = dcwidth - textwidth - 2

    dc.SetClippingRegion(0, 0, dcwidth, dcheight)
    dc.DrawText(text, x, y)

Josu states that it only works on wxMSW, and he is correct. Under wxGTK, it
seems that EVT_PAINT is never called from a text control. Does anyone know
why? Is there any workaround?

I tried calling the routine from EVT_KILL_FOCUS, and I tried using
wxClientDC instead of wxPaintDC. It half worked, but it cleared the entire
panel and drew the text on the panel !

If this problem will disappear when we move to GTK 2, I don't mind waiting a
few weeks.

Any assistance will be much appreciated.

Frank Millman

Hello,

Less ugly fix:
wxGlade is great for GUI design. Do your GUI magic in another file
that imports and uses MyFrame. Then if you need to do GUI reworking,
you don't lose your GUI magic. wxGlade is pretty good at taking care
of your code vs its code, but I don't trust anyone else not to
overwrite my code.

That sounds like a fabulous idea, but I'm scratching my head to a
polished chromedome trying to wrap my peabrain around it. So you
would keep the wxGlade generated code in say, MyGUI.py and the
functions the GUI is supposed to execute in say MyAPP.py? Then
instantiate MyFrame in MyAPP.py or somesuch like in your DemoApp
class? The events would still go into MyGUI I take it, but where
would OnExit() go? If all the functions go into into MyGUI.py
anyway, then what's the point?

You have basically two options:

1. Mix your code and the wxGlade-generated one in the same file, as Chris
   showed in his example: this works and should be safe as long as you
   "keep out" of the "wxGlade-regions", i.e. portions of code enclosed in
   # begin wxGlade ...
   # end wxGlade
   tags

2. Put a logic on a separate class, derived from the wxGlade-generated
   one, which will be on a different file.
   A quick example of this:

# file a.py - generated by wxGlade

ID_EXIT = wxNewId()

class MyFrame(wxFrame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wxDEFAULT_FRAME_STYLE
        wxFrame.__init__(self, *args, **kwds)

        # Menu Bar
        self.frame_1_menubar = wxMenuBar()
        self.SetMenuBar(self.frame_1_menubar)
        wxglade_tmp_menu = wxMenu()
        wxglade_tmp_menu.Append(ID_EXIT, "Exit", "Blow This
                                Popstand!")
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
        # Menu Bar end

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame_1")
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wxBoxSizer(wxVERTICAL)
        self.SetAutoLayout(1)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        sizer_1.SetSizeHints(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame

# now, file b.py - "generated" by you

import a

class MyRealFrame(a.MyFrame):
    def __init__(self, *args, **kwds):
        a.MyFrame.__init__(self, *args, **kwds)
        # now, let's bind the event you wanted
        EVT_MENU(self, a.ID_EXIT, self.OnExit)

    def OnExit(self, event):
        self.Close(True)

# end of class MyRealFrame

I think option 2) is cleaner, but this depends a lot on your taste (and
the situation). The only problem I see is that you may need to tweak the
generated file a bit in order to make the menu IDS global variables: at
the moment wxGlade either generates them as local variables in the
__init__ body, or does not generate them at all: I'll try to tell the
author to find a solution for this :stuck_out_tongue_winking_eye:

HTH,
Alberto

* Eladio Ventura <eladioventura@yahoo.com> [030415 15:20]:

That sounds like a fabulous idea, but I'm scratching my head to a
polished chromedome trying to wrap my peabrain around it. So you would
keep the wxGlade generated code in say, MyGUI.py and the functions the
GUI is supposed to execute in say MyAPP.py? Then instantiate MyFrame
in MyAPP.py or somesuch like in your DemoApp class? The events would
still go into MyGUI I take it, but where would OnExit() go? If all the
functions go into into MyGUI.py anyway, then what's the point?

I would simply KILL for an example of this scheme. Any ideas? Or maybe I
should wait until I have gleaned through demo.py.

Never mind. I'm an idiot. It was just a question of keeping the events
in MyGUI and then import the fancy popup dialogs and stuff from another
file. Easy as pie!

···

--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

Frank Millman wrote:

Hi all,

I am trying to use the right-aligned text control that was kindly
contributed by Josu Oyanguren in one the earlier demos. It is a subclass of
wxTextCtrl that traps an EVT_PAINT event, and then does the following -

def OnPaint(self, event):
    dc = wxPaintDC(self)
    dc.SetFont(self.GetFont())
    dc.Clear()
    text = self.GetValue()
    textwidth, textheight = dc.GetTextExtent(text)
    dcwidth, dcheight = self.GetClientSizeTuple()

    y = (dcheight - textheight) / 2
    x = dcwidth - textwidth - 2

    dc.SetClippingRegion(0, 0, dcwidth, dcheight)
    dc.DrawText(text, x, y)

Josu states that it only works on wxMSW, and he is correct. Under wxGTK, it
seems that EVT_PAINT is never called from a text control. Does anyone know
why?

In wxGTK many controls are not true windows but are just drawn directly on their parent. I didn't think that wxTextCtrl was this way but it could be.

Is there any workaround?

Not that I know of, other than padding the value with leading spaces...

I tried calling the routine from EVT_KILL_FOCUS, and I tried using
wxClientDC instead of wxPaintDC. It half worked, but it cleared the entire
panel and drew the text on the panel !

Yep, see above.

If this problem will disappear when we move to GTK 2, I don't mind waiting a
few weeks.

I think that the widget in GTK2 does support right-aligned text, but I don't know if wxGTK2 is supporting it yet. Doesn't look like it is doing anything with the wxTE_RIGHT style in the code. Enter a feature request for it so it doesn't get lost.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Less ugly fix:
wxGlade is great for GUI design. Do your GUI magic in another file that
imports and uses MyFrame. Then if you need to do GUI reworking, you don't
lose your GUI magic. wxGlade is pretty good at taking care of your code vs
its code, but I don't trust anyone else not to overwrite my code.

That sounds like a fabulous idea, but I'm scratching my head to a
polished chromedome trying to wrap my peabrain around it. So you would
keep the wxGlade generated code in say, MyGUI.py and the functions the
GUI is supposed to execute in say MyAPP.py? Then instantiate MyFrame
in MyAPP.py or somesuch like in your DemoApp class? The events would
still go into MyGUI I take it, but where would OnExit() go? If all the
functions go into into MyGUI.py anyway, then what's the point?

I would simply KILL for an example of this scheme. Any ideas? Or maybe I
should wait until I have gleaned through demo.py.

You're pretty much on the money, its just the details:

This is a very ugly example, but it works. I usully put menu stuff in with the rest of event functions - it seems to grow very quickly when I'm adding features, and seems more relevant there. To my mind it seems more of an application detail rather than gui detail, but that may just be the way my mind works.

Ugly detail - passing around ID_EXIT. There's a better way, but I couldn't come up with it right now (I have an appointment with my 3yo daughter to play Barbie's with here - sorry).

Carefull using names like OnExit which get called when exiting for functions which you are connecting to events.

temp1.py is the wxGlade generated file.
temp2.py is the application stuff.

Have fun,

Chris.

temp1.py (1.28 KB)

temp2.py (463 Bytes)

WOW! Thank you Alberto and Chris - your examples *really* made my day.
Now I can keep the wxGlade code in one file, the "meat" of the
application functions in another and the "gui magic" in another. This is
*so* much more clear-cut and easy to work with. You guys really shifted
a programming paradigm for me.

Fantastic! I hope the wiki will incorporate your example, Chris. Stuff
like that just isn't obvious to us newbie folks. :0)

···

--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

Glad it helped. Do your own karma the world of good and put it in the wiki while its fresh in your mind!

···

----- Original Message -----
From: Eladio Ventura
To: wxPython-users@lists.wxwindows.org
Sent: Wednesday, April 16, 2003 8:03 PM
Subject: Re: [wxPython-users] wxGlade and Events. HOW?!

WOW! Thank you Alberto and Chris - your examples *really* made my day.
Now I can keep the wxGlade code in one file, the "meat" of the
application functions in another and the "gui magic" in another. This is
*so* much more clear-cut and easy to work with. You guys really shifted
a programming paradigm for me.

Fantastic! I hope the wiki will incorporate your example, Chris. Stuff
like that just isn't obvious to us newbie folks. :0)
--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

* Chris Munchenberg <cjm@ava.com.au> [030416 18:29]:

Glad it helped. Do your own karma the world of good and put it in the wiki while its fresh in your mind!

Great idea. I've never done a wiki before, but I'll hit the docs this
evening and see what I can whip up. It sure would make a nice addition.

···

--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

* Eladio Ventura <eladioventura@yahoo.com> [030416 15:33]:

Great idea. I've never done a wiki before, but I'll hit the docs this
evening and see what I can whip up. It sure would make a nice addition.

I finished the Wiki. You'll find it under RecipesOther, OrganizingYourCode.
Yeah, incredibly imaginative title, but it gets the work done. I saved
it, but it hasn't been added yet. Probably normal. Like a jerk I didn't
save a copy on my PC. Probably normal too. Anyway, my first Wiki.

WHOOHOO!

···

--
"Thinking gives you wrinkles!"
Malibu Stacy, the Simpsons

Eladio Ventura wrote:

* Eladio Ventura <eladioventura@yahoo.com> [030416 15:33]:

Great idea. I've never done a wiki before, but I'll hit the docs this
evening and see what I can whip up. It sure would make a nice addition.

I finished the Wiki. You'll find it under RecipesOther, OrganizingYourCode. Yeah, incredibly imaginative title, but it gets the work done. I saved
it, but it hasn't been added yet. Probably normal. Like a jerk I didn't
save a copy on my PC.

One of the features of a wiki is that your docs are published immediately. Perhaps the old page was still in your cache or something...

Thanks for adding the page!

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Frank Millman wrote:
> Hi all,
>
> I am trying to use the right-aligned text control that was kindly
> contributed by Josu Oyanguren in one the earlier demos. It is a subclass

of

> wxTextCtrl that traps an EVT_PAINT event, and then does the following -
>
>
> Josu states that it only works on wxMSW, and he is correct. Under wxGTK,

it

> seems that EVT_PAINT is never called from a text control. Does anyone

know

> why?

Robin Dunn wrote:

In wxGTK many controls are not true windows but are just drawn directly
on their parent. I didn't think that wxTextCtrl was this way but it
could be.

> Is there any workaround?

Not that I know of, other than padding the value with leading spaces...

Thanks, Robin. This is such an obvious idea that it did not occur to me. It
works quite well. It is not perfect, because, sticking to the default fonts,
a space takes up 4 pixels on Linux and 3 pixels on Windows. This means that
in a worst case the right hand margin can be misaligned by 3 or 2 pixels
respectively, and this is noticeable. I guess I should start looking into
using a fixed-pitch font for numeric controls.

I think that the widget in GTK2 does support right-aligned text, but I
don't know if wxGTK2 is supporting it yet. Doesn't look like it is
doing anything with the wxTE_RIGHT style in the code. Enter a feature
request for it so it doesn't get lost.

I have entered a request to add support for wxTE_RIGHT under GTK2. I have
also entered a request to add support for EVT_PAINT in a wxTextCtrl under
GTK2. I understand from your comments above that this may not be possible,
but if it could be done it would be great.

Many thanks

Frank Millman