Mouse right click events possible on wx.StaticText ?: events not getting picked up

Hi I am trying to bind a mouse event to some StaticText objects. Basically I want contextual popups around some Static textobjects in my GUI

Here is some test code ( see below), but somehow my events are going un-listened to.

I have no clue why the event is not picked up . I am testing it on Linux .

Thanks for your help
Hari

import wx
import wx.lib.inspection

class aFrame(wx.Frame):

def __init__(self,*args , **kwds):
    kwds["size"]  = (640,480)
    wx.Frame.__init__(self,*args,**kwds)
    self.sizer = wx.BoxSizer(wx.VERTICAL)
    self.text = wx.StaticText(self,-1,"Hello Right Click me",style=wx.ALIGN_CENTER)
    self.sizer.Add((1,1),1)
    self.sizer.Add(self.text,0,wx.ALIGN_CENTER|wx.EXPAND)
    self.sizer.Add((1,1),1)
    self.Bind(wx.EVT_RIGHT_DOWN,self.Onrightclick,self.text)
    self.SetSizer(self.sizer)
    self.sizer.Layout()

def Onrightclick(self,event):
    print "Right click recvd"

if name==“main”:
app = wx.PySimpleApp()
f = aFrame(None,-1 , “test right click”)
f.Show()
wx.lib.inspection.InspectionTool().Show()
app.MainLoop()

Hello,

···

On Tue, Jul 21, 2009 at 8:49 AM, hari jayaram<harijay@gmail.com> wrote:

Hi I am trying to bind a mouse event to some StaticText objects. Basically I
want contextual popups around some Static textobjects in my GUI

Here is some test code ( see below), but somehow my events are going
un-listened to.

I have no clue why the event is not picked up . I am testing it on Linux .

You can try (self.text.Bind(...)) to see if it works (see
self.Bind vs. self.button.Bind - wxPyWiki).

But IIRC on GTK (linux) the static text widget is not really its own
window, it is just drawn on its parent, so I am not sure if mouse
events will work with it or not.

Cody

If Cody is correct, than the first workaround that popped into my mind
is to track your mouse position and bind the click event to the panel
or the frame. Then you can have it check if the mouse position is over
the static text "widget" and execute it accordingly.

- Mike

···

On Jul 21, 9:15 am, Cody Precord <codyprec...@gmail.com> wrote:

Hello,

On Tue, Jul 21, 2009 at 8:49 AM, hari jayaram<hari...@gmail.com> wrote:
> Hi I am trying to bind a mouse event to some StaticText objects. Basically I
> want contextual popups around some Static textobjects in my GUI

> Here is some test code ( see below), but somehow my events are going
> un-listened to.

> I have no clue why the event is not picked up . I am testing it on Linux .

You can try (self.text.Bind(...)) to see if it works (seehttp://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind).

But IIRC on GTK (linux) the static text widget is not really its own
window, it is just drawn on its parent, so I am not sure if mouse
events will work with it or not.

Cody

Thanks a tonne Cody for your answer .
Calling it as suggested ( self.child.Bind) fixed the problem . I can now pick up right-click events from StaticText widgets using

self.text.Bind(wx.EVT_RIGHT_DOWN,self.Onrightclick)

Also thanks for the pointer to the page that talks about the difference between self.Bind and self.child.Bind()

The graphic by Don Ingle at that page really made things a lot clearer. But I have one additional question.

Can a non command event like wx.EVT_RIGHT_DOWN when caught by self.child.Bind() be skipped and passed on to the parent frame for whatever reason. I understood that the non command event if not caught by the child then does not propagate up. But if it is caught and then skipped can it then be propagated up. The code below seems to suggest that it cannot be propagated once caught.

import wx
import wx.lib.inspection

class aFrame(wx.Frame):

def __init__(self,*args , **kwds):
    kwds["size"]  = (640,480)
    wx.Frame.__init__(self,*args,**kwds)
    self.sizer = wx.BoxSizer(wx.VERTICAL)
    self.text = wx.StaticText(self,-1,"Hello Right Click me",style=wx.ALIGN_CENTER)
    self.sizer.Add((1,1),1)
    self.sizer.Add(self.text,0,wx.ALIGN_CENTER|wx.EXPAND)
    self.sizer.Add((1,1),1)
    # This binding detects the right click immediately see [http://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind](http://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind)
   
    self.text.Bind(wx.EVT_RIGHT_DOWN,self.Onrightclick)
   
    # test to see if the event can be skipped  and recaught by parent frame
   
    self.Bind(wx.EVT_RIGHT_DOWN,self.ParentClick,self.text)
    self.SetSizer(self.sizer)
    self.sizer.Layout()

def Onrightclick(self,event):
    print "Right click recvd"
    event.Skip()

def ParentClick(self,event):
    print "Right click recvd on parent"

if name==“main”:
app = wx.PySimpleApp()
f = aFrame(None,-1 , “test right click”)
f.Show()
wx.lib.inspection.InspectionTool().Show()
app.MainLoop()

···

On Tue, Jul 21, 2009 at 10:38 AM, Mike Driscoll kyosohma@gmail.com wrote:

On Jul 21, 9:15 am, Cody Precord codyprec...@gmail.com wrote:

Hello,

On Tue, Jul 21, 2009 at 8:49 AM, hari jayaramhari...@gmail.com wrote:

Hi I am trying to bind a mouse event to some StaticText objects. Basically I

want contextual popups around some Static textobjects in my GUI

Here is some test code ( see below), but somehow my events are going

un-listened to.

I have no clue why the event is not picked up . I am testing it on Linux .

You can try (self.text.Bind(…)) to see if it works (seehttp://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind).

But IIRC on GTK (linux) the static text widget is not really its own

window, it is just drawn on its parent, so I am not sure if mouse

events will work with it or not.

Cody

If Cody is correct, than the first workaround that popped into my mind

is to track your mouse position and bind the click event to the panel

or the frame. Then you can have it check if the mouse position is over

the static text “widget” and execute it accordingly.

  • Mike

hari jayaram wrote:

Can a non command event like wx.EVT_RIGHT_DOWN when caught by self.child.Bind() be skipped and passed on to the parent frame for whatever reason. I understood that the non command event if not caught by the child then does not propagate up. But if it is caught and then skipped can it then be propagated up.

No, Skip() just says to continue the normal event propagation, whatever it would have been if the event binding did not exist. There is a way to cause the event to propagate however, just call event.ResumePropagation(1) in addition to Skip and that will tell the event system to propagate the event up to the parent.

···

--
Robin Dunn
Software Craftsman

Thanks Robin, for your email on event propagation.
So accordingly, I can modify the previous example to catch the event by setting the propagation level:
And now the other window can also receive the command and non command events by tuning the propagation level:

Modified code pasted below:
Hari

import wx
import wx.lib.inspection

class aFrame(wx.Frame):

def __init__(self,*args , **kwds):
    kwds["size"]  = (640,480)
    wx.Frame.__init__(self,*args,**kwds)
    self.sizer = wx.BoxSizer(wx.VERTICAL)
    self.text = wx.StaticText(self,-1,"Hello Right Click me",style=wx.ALIGN_CENTER)
    self.sizer.Add((1,1),1)
    self.sizer.Add(self.text,0,wx.ALIGN_CENTER|wx.EXPAND)
    self.sizer.Add((1,1),1)
    # This binding detects the right click immediately see [http://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind](http://wiki.wxpython.org/self.Bind%20vs.%20self.button.Bind)

    self.text.Bind(wx.EVT_RIGHT_DOWN,self.Onrightclick)

    # test to see if the event can be skipped  and recaught by parent frame

    self.Bind(wx.EVT_RIGHT_DOWN,self.ParentClick,self.text)

    self.SetSizer(self.sizer)
    self.sizer.Layout()

def Onrightclick(self,event):
    print "Right click recvd"
    event.Skip()
    event.ResumePropagation(1)

def ParentClick(self,event):
    print "Right click recvd on parent"

if name==“main”:
app = wx.PySimpleApp()
f = aFrame(None,-1 , “test right click”)
f.Show(1)
wx.lib.inspection.InspectionTool().Show(1)
app.MainLoop()

···

On Tue, Jul 21, 2009 at 2:23 PM, Robin Dunn robin@alldunn.com wrote:

hari jayaram wrote:

Can a non command event like wx.EVT_RIGHT_DOWN when caught by

self.child.Bind() be skipped and passed on to the parent frame for

whatever reason. I understood that the non command event if not caught

by the child then does not propagate up. But if it is caught and then

skipped can it then be propagated up.

No, Skip() just says to continue the normal event propagation, whatever

it would have been if the event binding did not exist. There is a way

to cause the event to propagate however, just call

event.ResumePropagation(1) in addition to Skip and that will tell the

event system to propagate the event up to the parent.

Robin Dunn

Software Craftsman

http://wxPython.org