Hi!
I’m beginning with wxPython.
Environment: Linux (GTK), wxPython 4.2.0
I need to implement a mouse-event listener monitoring the whole screen (my app is running fullscreen).
A way I used with other GUIs was to bind a listener to a transparent panel covering the whole screen.
I’m discovering that it’s not possible with wxPython because mouse events do not propagate through the chain of event handlers. So only the lowest level will receive the event.
I read that I can subclass EventHandler and use tryBefore() or tryAfter() but it looks like an ugly hack.
Is there a better way to solve my problem?
Here’s a runnable program (Matplotlob is required).
#!/usr/bin/python3
import matplotlib as mpl
mpl.use( 'wxAgg')
import wx
class UpperPanel( wx.Panel):
def __init__( self, parent):
wx.Panel.__init__( self, parent)
self.create_MPL()
self.createTools()
self.Bind( wx.EVT_MOUSE_EVENTS, self.actMouse)
self.sz1 = wx.BoxSizer( wx.VERTICAL)
self.sz1.Add( self.canvas, proportion=1, flag=wx.TOP | wx.EXPAND)
self.sz1.Add( self.tools_MPL, proportion=0, flag=wx.BOTTOM)
self.sz2 = wx.BoxSizer( wx.VERTICAL)
self.sz2.Add( self.tools, proportion=0, flag=wx.TOP )
self.sz3 = wx.BoxSizer( wx.HORIZONTAL)
self.sz3.Add( self.sz1, proportion=1, flag=wx.EXPAND)
self.sz3.Add( self.sz2, proportion=0)
self.SetSizer( self.sz3)
def create_MPL( self):
import matplotlib.figure
import matplotlib.backends.backend_wxagg
self.fig = matplotlib.figure.Figure( layout='constrained')
self.ax = self.fig.add_subplot(111)
self.canvas = mpl.backends.backend_wxagg.FigureCanvasWxAgg( self, -1, self.fig)
self.tools_MPL = mpl.backends.backend_wxagg.NavigationToolbar2WxAgg( self.canvas)
self.tools_MPL.Realize()
def toolButton( self, label, handler):
btn = wx.Button( self, wx.ID_ANY, label=label)
btn.Bind( wx.EVT_BUTTON, handler, btn)
self.tools.Add( btn, proportion=0, flag=wx.ALL | wx.CENTER, border=5)
def createTools( self):
self.tools = wx.BoxSizer( wx.VERTICAL) # create toolbox
self.toolButton( 'T', self.action)
self.toolButton( 'F', self.action)
def action( self, event):
print( 'Action on', event.GetEventObject().LabelText)
def actMouse( self, év):
cmd = év.GetEventObject()
print( "Pos:",wx.GetMousePosition())
év.Skip( True)
class Win( wx.Frame):
def __init__( self):
wx.Frame.__init__( self, None, -1, size=(1200,900))
self.panel = UpperPanel( self)
class App( wx.App):
def OnInit( self):
win = Win()
self.SetTopWindow( win)
win.Show( True)
return True
if __name__ == "__main__" :
app = App( False)
app.MainLoop()
I’m expecting mouse motion events over the whole app but I don’t get any over the Matplotlib canvas or Matplotlib toolbar and even over my own buttons (on right side).
Where’s my problem?