[wxPython] Absolute beginner...get who caused event

call "event.GetId()" in your generic callback and you will get the identifier of the control which posted the event.

···

From: Magnus Lycka <magnus@thinkware.se>
Reply-To: wxpython-users@lists.sourceforge.net
To: wxpython-users@lists.sourceforge.net
Subject: [wxPython] Absolute beginner...get who caused event
Date: Sun, 18 Feb 2001 01:35:10 +0100

This is my first try with wxPython, and I haven't done
a lot of GUI programming (just GUI 'painting') before.

I thought I'd make a little calculator, and thus I made
buttons with digits etc. These all call a frame method
self.OnPressMe through EVT_BUTTON.

Then my thought was that OnPressMe(self, event) should
figure out which button was pressed, and then know
what to do.

I could obviously make one call-back function for
each button, but I got this idea that I would be able
to use the text on the button and 'eval' to basically
make this program without coding...

So, how does OnPressMe figure out which button was
pressed?

/Magnus
<< magnus.vcf >>

_________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com.

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I wanted to get a reference to the control which
caused an event. In this case, which button was
pressed.

Paul-Marie Boulanger wrote:

call "event.GetId()" in your generic callback and you will get the
identifier of the control which posted the event.

Ok, this works... First a question.

Why doesn't dir(event) etc work? I just see this and thisown. Not
the methods available.

Secondly, over to the main issue.

GetId() returns the "windows identifier", which is an integer.
How does this help me to get hold of the control itself? I solved
it now by making a dict where I keyed the buttons on their id,
but I imagine this is redundant. Is there a function that takes
an id and returns the control / widget?

In the frame __init__ I have this:
        ...
        self.dBut = {}
        arButton = [['7','8','9','/'],
                    ['4','5','6','*'],
                    ['1','2','3','-'],
                    ['0','.','=','+']]
        ypos = 0
        for y in arButton:
            xpos = 0
            for x in y:
                id = 1000+xpos+ypos*10
                button = wxButton(panel, id, x, size=wxSize(28,28))
                button.SetPosition(wxPoint(xpos * 30, 30 + ypos * 30))
                EVT_BUTTON(self, id, self.OnPressMe)
                self.dBut[id] = button
                xpos += 1
            ypos += 1
        ...

and then:
    def OnPressMe(self, event):
        print self.dBut[event.GetId()].GetLabel()

(Yes, I intend to add some real functionality as well!)

I imagine I could skip the whole self.dBut and just call an
appropriate function (which I haven't found in the docs yet).
A hint please!

/Magnus

Hello,

I've been using wxPython in my primary GUI driver for my application.
However I've accross some issues I haven't been able to figure out.

My application attempts to intercept all UI events, perform validation on
those events or their actions, then manually updates the widgets. I don't
want the widgets doing much if anything on their own. However I can't
seem to get the wxComboBox to pass me the up/down arrow keyboard events
which I want to override.

Also the toolbar in windows is acting oddly. The png's are being spread
across multiple buttons. It's probably best shown with a screenshot

http://goats.gnue.org/~jamest/toolbar.png
(96k image)
The disk imagee in the first button is cut off and continued in the second
button. On linux and solaris they look fine.

Finally labels on top of png's are filling in a background color on win32.
Again, on linux and solaris this looks fine with the background showing
through properly. A screenshot is at

http://goats.gnue.org/~jamest/login.png
(156k image)

Thanks for any assistance you can provide,
James

->->->->->->->->->->->->->->->->->->---<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
James Thompson 138 Cardwell Hall Manhattan, Ks 66506 785-532-0561 Kansas
State University Department of Mathematics
->->->->->->->->->->->->->->->->->->---<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<

···

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Why doesn't dir(event) etc work? I just see this and thisown. Not
the methods available.

Because SWIG, the tool Robin uses to generate the Python/C++ interface code,
doesn't currently fill in the Python __methods__attribute of the
wxWhateverEvent instance... I think, however, that Robin may be working on
this for an upcoming release...? In the meantime, it's not too hard to rely
on, largely, the documentation... incidentally, I often find the "PyTree"
demo useful just to check which fact septa C++ objects are indeed mirrored
by wxPython... perhaps I should trust the list in the documentation itself
up, but...

GetId() returns the "windows identifier", which is an integer.
How does this help me to get hold of the control itself? I solved
it now by making a dict where I keyed the buttons on their id,
but I imagine this is redundant. Is there a function that takes
an id and returns the control / widget?

Try wxFindWindowById() {in the docs, look in Functions->Miscellaneous}. Be
aware, though, that currently this always returns a wxWindow instance, even
though it might actually represent some subclass (in fact it usually will).
This is what I think Robin may be working on, but for now you may find the
wxPyTypecast function (see wx.py) useful. E.g.,
wxPyTypecast(wxFindWindowById({whatever goes here, presumably the ID--see
docs}),"wxButton") ...

Cheerio, Chris

···

-------------------------------------------------------------------------
Chris Fama <mailto:Chris.Fama@whollysnakes.com> Phone:(07) 3870 5639
Brisbane, Australia Mobile:(0400) 833 700
-------------------------------------------------------------------------

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I wanted to get a reference to the control which
caused an event. In this case, which button was
pressed.

Paul-Marie Boulanger wrote:
>
> call "event.GetId()" in your generic callback and you will get the
> identifier of the control which posted the event.

Ok, this works... First a question.

Why doesn't dir(event) etc work? I just see this and thisown. Not
the methods available.

Because that's all that's in the instance object. The methods are
attributes of the class. Try dir(event.__class__)

Secondly, over to the main issue.

GetId() returns the "windows identifier", which is an integer.
How does this help me to get hold of the control itself? I solved
it now by making a dict where I keyed the buttons on their id,
but I imagine this is redundant. Is there a function that takes
an id and returns the control / widget?

wxWindow.FindWindowById(theID) will recursivly search the window and its
children. What you get back is a shadow object around a wxWindow reference.
To change it into a wxButton object you'll need to use wxPyTypeCast. Search
the list archives for info on that.

Eventually FindWindowById and GetEventObject and others will return the
orginal Python object if it still exists, but for now we need to continue
using the workaround.

In the frame __init__ I have this:
        ...
        self.dBut = {}
        arButton = [['7','8','9','/'],
                    ['4','5','6','*'],
                    ['1','2','3','-'],
                    ['0','.','=','+']]
        ypos = 0
        for y in arButton:
            xpos = 0
            for x in y:
                id = 1000+xpos+ypos*10
                button = wxButton(panel, id, x, size=wxSize(28,28))
                button.SetPosition(wxPoint(xpos * 30, 30 + ypos * 30))
                EVT_BUTTON(self, id, self.OnPressMe)
                self.dBut[id] = button
                xpos += 1
            ypos += 1
        ...

A trick I have used in the past is to use the actual value as the ID of the
button. (or its ascii value, or as an offset from 10000, or whatever...)
Then you can translate GetId directly to the value you are looking for.

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I've been using wxPython in my primary GUI driver for my application.
However I've accross some issues I haven't been able to figure out.

My application attempts to intercept all UI events, perform validation on
those events or their actions, then manually updates the widgets. I don't
want the widgets doing much if anything on their own. However I can't
seem to get the wxComboBox to pass me the up/down arrow keyboard events
which I want to override.

Which events are you trying to catch?

Also the toolbar in windows is acting oddly. The png's are being spread
across multiple buttons. It's probably best shown with a screenshot

http://goats.gnue.org/~jamest/toolbar.png
(96k image)
The disk imagee in the first button is cut off and continued in the second
button. On linux and solaris they look fine.

Did you call toolBar.SetToolBitmapSize()?

Finally labels on top of png's are filling in a background color on win32.
Again, on linux and solaris this looks fine with the background showing
through properly. A screenshot is at

http://goats.gnue.org/~jamest/login.png
(156k image)

On GTK the static text is not a real widget, it is just drawn on its parent
window. On MSW it is a true window, and so it will occlude what's behind it
like any other window. You can try using a wxTRANSPARENT_WINDOW style flag,
but I'm not sure if it will work or not. Another thing to try is to give
the static text an event handler for EVT_ERASE_BACKGROUND that does nothing.
If none of those work then you'll probably have to make your own control, or
just draw the text on the background window yourself in its EVT_PAINT event.

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

> My application attempts to intercept all UI events, perform validation on
> those events or their actions, then manually updates the widgets. I don't
> want the widgets doing much if anything on their own. However I can't
> seem to get the wxComboBox to pass me the up/down arrow keyboard events
> which I want to override.

Which events are you trying to catch?

Basically all of them :slight_smile: But EVT_CHAR is giving me trouble at this
time. Here's how I create it.....

newWidget = wxComboBox(container, -1, "",
      wxPoint(int(object.x)*int(self.widgetWidth),
      (int(object.y)+spacer+(gap*spacer))*int(self.widgetHeight)),
      wxSize(int(object.width)*int(self.textWidth),
      int(object.height)*int(self.textHeight)),
      choices, wxCB_DROPDOWN)
newWidget.SetValue("")

EVT_CHAR(newWidget, self.uiEventTrap)
EVT_COMBOBOX(newWidget, newWidget.GetId(), self.uiEventTrap)

Now if I'm in the combobox and I press the letter "a" then the
self.uiEventTrap sees it as type wxEVT_CHAR. However if I press the up or
down arrows on the keyboard (WXK_UP or WXK_DOWN) the combo box changes
selected value instead of passing the event to uiEventTrap.

While I'm not 100% sold on altering the default behaviour of the comboBox
my application moves thru records via the up/down arrows and I do have
some users that find the non-standard (for this application) behaviour
on comboBoxes annoying.

> The disk imagee in the first button is cut off and continued in the second
> button. On linux and solaris they look fine.

Did you call toolBar.SetToolBitmapSize()?

It worked. Thanks!

On GTK the static text is not a real widget, it is just drawn on its parent
window. On MSW it is a true window, and so it will occlude what's behind it
like any other window. You can try using a wxTRANSPARENT_WINDOW style flag,
but I'm not sure if it will work or not. Another thing to try is to give
the static text an event handler for EVT_ERASE_BACKGROUND that does nothing.
If none of those work then you'll probably have to make your own control, or
just draw the text on the background window yourself in its EVT_PAINT event.

A quick test of wxTRANSPARENT_WINDOW didn't work. I'll try the other
suggestions when I have a free moment to read up on them.

Thanks again for the assistance,
James

->->->->->->->->->->->->->->->->->->---<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
James Thompson 138 Cardwell Hall Manhattan, Ks 66506 785-532-0561
Kansas State University Department of Mathematics
->->->->->->->->->->->->->->->->->->---<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<

···

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Robin Dunn wrote:

Because that's all that's in the instance object. The methods are
attributes of the class. Try dir(event.__class__)

Ok, I'd prefer that it wasn't hiding like that though. :wink:
It's not entirely newbie-helpful. :wink:

wxWindow.FindWindowById(theID) will recursivly search the window and its
children. What you get back is a shadow object around a wxWindow reference.
To change it into a wxButton object you'll need to use wxPyTypeCast. Search
the list archives for info on that.

Thanks. Just what I was looking for. I didn't even have to cast it
to use GetLabel(). I certainly prefer this to encoding information
in the ID.

The demo is very useful of course, few things can beat real examples,
but a continuation of the tutorial would be very nice as well...

/Magnus