EVT_MOUSEWHEEL has no effect in a wxBitmap

Cliff - the problem is that on my computer, the line:

EVT_MOUSEWHEEL(self.bitmap, self.OnM)

doesn't catch any events... the function self.OnM is never called, while the line:

EVT_MOUSEWHEEL(self, self.OnM)

does catch the events for the frame.

Robin - I'm using Python 2.2 with wxPython 2.3.3.1 under winXP. I will try making my own control for displaying a bitmap (its good practice :D), could you - in a few lines - describe how I would do that? For example, I assume I need to derive an object from wxWindow, wxControl, wxObject and wxEvtHandler (like wxStaticBitmap is), but after that I don't know where to go with it...

Amos Joshua wrote:

Cliff - the problem is that on my computer, the line:

EVT_MOUSEWHEEL(self.bitmap, self.OnM)

doesn't catch any events... the function self.OnM is never called, while the line:

EVT_MOUSEWHEEL(self, self.OnM)

does catch the events for the frame.

Robin - I'm using Python 2.2 with wxPython 2.3.3.1 under winXP. I will try making my own control for displaying a bitmap (its good practice :D), could you - in a few lines - describe how I would do that? For example, I assume I need to derive an object from wxWindow, wxControl, wxObject and wxEvtHandler (like wxStaticBitmap is), but after that I don't know where to go with it...

Look at wxPython/lib/buttons.py or stattext.py. Those are examples of doing custom button or static text controls. Doing a wxStaticBitmap clone should be very similar.

···

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

Robin Dunn wrote:

Amos Joshua wrote:

Cliff - the problem is that on my computer, the line:

EVT_MOUSEWHEEL(self.bitmap, self.OnM)

doesn’t catch any events… the function self.OnM is never called, while the line:

EVT_MOUSEWHEEL(self, self.OnM)

does catch the events for the frame.

Robin - I’m using Python 2.2 with wxPython 2.3.3.1 under winXP. I will try making my own control for displaying a bitmap (its good practice :D),
could you - in a few lines - describe how I would do that? For example,
I assume I need to derive an object from wxWindow, wxControl, wxObject and
wxEvtHandler (like wxStaticBitmap is), but after that I don’t know where
to go with it…

Look at wxPython/lib/buttons.py or stattext.py. Those are examples of doing custom button or static text controls. Doing a wxStaticBitmap clone
should be very similar.

Yes, thank you. I have built the class, however, the problem remains! Attached is an application that demonstrates the problem - the mouse wheel event is not triggered for the bitmap object, but is for the frame.

bit.zip (1.46 KB)

Cliff - the problem is that on my computer, the line:

EVT_MOUSEWHEEL(self.bitmap, self.OnM)

doesn't catch any events... the function self.OnM is never called,
while
the line:

Hm. Must be something with the Win32 libs. It works fine on GTK+.

EVT_MOUSEWHEEL(self, self.OnM)

does catch the events for the frame.

Robin - I'm using Python 2.2 with wxPython 2.3.3.1 under winXP. I will
try making my own control for displaying a bitmap (its good practice
:D), could you - in a few lines - describe how I would do that? For
example, I assume I need to derive an object from wxWindow, wxControl,
wxObject and wxEvtHandler (like wxStaticBitmap is), but after that I
don't know where to go with it...

Try this:

from wxPython.wx import *

class BitmapPanel(wxPanel):
    def __init__(self, parent, id, bitmap):
        wxPanel.__init__(self, parent, id,
                         size = (bitmap.GetWidth(), bitmap.GetHeight()))
        self.bitmap = bitmap
        EVT_PAINT(self, self.OnPaint)

    def Draw(self, dc):
        dc.DrawBitmap(self.bitmap, 0, 0)

    def OnPaint(self, event):
        dc = wxPaintDC(self)
        self.Draw(dc)

class MyFrame(wxFrame):
    def __init__(self, parent, id, title):
        wxFrame.__init__(self, parent, id, title,
                         wxPoint(100, 100), wxSize(500, 400))
        EVT_CLOSE(self, self.OnCloseWindow)
        self.panel = wxPanel(self, -1)
        self.bitmap = BitmapPanel(self.panel, -1,
                                  bitmap =
wxBitmap('/usr/share/pixmaps/XMMS1.png'))
# EVT_MOUSEWHEEL(self, self.OnM)
        EVT_MOUSEWHEEL(self.bitmap, self.OnM)
        
    def OnCloseWindow(self, event):
        self.Destroy()
        
    def OnM(self, event):
        print event
        # print GetWheelRotation()

class MyApp(wxApp):
    def OnInit(self):
        wxInitAllImageHandlers()
        self.frame = MyFrame(None, -1, "TITLE")
        self.frame.Show(true)
        self.SetTopWindow(self.frame)
        return true
    
app = MyApp(0)
app.MainLoop()

···

On Thu, 2003-01-02 at 04:08, Amos Joshua wrote:

--
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 x308 (800) 735-0555 x308

Cliff Wells wrote:

Try this:

from wxPython.wx import *

class BitmapPanel(wxPanel):
    def __init__(self, parent, id, bitmap):
        wxPanel.__init__(self, parent, id,
                         size = (bitmap.GetWidth(), bitmap.GetHeight()))

Deriving from wxPyControl would be a bit better as then you could override things like DoGetBestSize and such and then it will work a little better with the rest of wxWindows (like sizers.)

···

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

Amos Joshua wrote:

Robin Dunn wrote:

Amos Joshua wrote:

Cliff - the problem is that on my computer, the line:

EVT_MOUSEWHEEL(self.bitmap, self.OnM)

doesn't catch any events... the function self.OnM is never called, while the line:

EVT_MOUSEWHEEL(self, self.OnM)

does catch the events for the frame.

Robin - I'm using Python 2.2 with wxPython 2.3.3.1 under winXP. I will try making my own control for displaying a bitmap (its good practice :D), could you - in a few lines - describe how I would do that? For example, I assume I need to derive an object from wxWindow, wxControl, wxObject and wxEvtHandler (like wxStaticBitmap is), but after that I don't know where to go with it...

Look at wxPython/lib/buttons.py or stattext.py. Those are examples of doing custom button or static text controls. Doing a wxStaticBitmap clone should be very similar.

Yes, thank you. I have built the class, however, the problem remains! Attached is an application that demonstrates the problem - the mouse wheel event is not triggered for the bitmap object, but is for the frame.

On MSW the window has to have the focus in order to get mouse wheel events. In your sample if you click on the bitmap first then you'll start getting the events. If you don't want to have to click first then you can do something like catch mouse overs and do a self.SetFocus(), or maybe a EVT_ENTER_WINDOW/EVT_LEAVE_WINDOW pair where you set the focus to the bitmap, and then restore it to the window that had it before when leaving.

···

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

Amos Joshua wrote:

Robin Dunn wrote:

Amos Joshua wrote:

Cliff - the problem is that on my computer, the line:

EVT_MOUSEWHEEL(self.bitmap, self.OnM)

doesn’t catch any events… the function self.OnM is never called, while the line:

EVT_MOUSEWHEEL(self, self.OnM)

does catch the events for the frame.

Robin - I’m using Python 2.2 with wxPython 2.3.3.1 under winXP. I will try making my own control for displaying a bitmap (its good practice :D),
could you - in a few lines - describe how I would do that? For example,
I assume I need to derive an object from wxWindow, wxControl, wxObject and
wxEvtHandler (like wxStaticBitmap is), but after that I don’t know where
to go with it…

Look at wxPython/lib/buttons.py or stattext.py. Those are examples of doing custom button or static text controls. Doing a wxStaticBitmap clone
should be very similar.

Yes, thank you. I have built the class, however, the problem remains!
Attached is an application that demonstrates the problem - the mouse wheel
event is not triggered for the bitmap object, but is for the frame.
Cliff, that class you gave me worked! There remains a phenomenon - the mouse wheel event is trigered now no matter where the wheel is turned (outside the
window too, that is), but

that problem was easy to overcome by running a hit test to see if the mouse is in the window or not.

Thanks alot! Thank you, Robin, too (also for the help with the bitmap/transparency issue).

Cliff, that class you gave me worked! There remains a phenomenon - the
mouse wheel event is trigered now no matter where the wheel is turned
(outside the window too, that is), but
that problem was easy to overcome by running a hit test to see if the
mouse is in the window or not.

Glad I could help. I suspect the reason the event is fired even outside
of the frame is that scrolling the wheel probably doesn't change the
focus away from the frame. So even though the event occurs outside the
frame, Windows still sends the event to whichever frame has the focus.
Sort of like moving the mouse outside of a frame and then typing on the
keyboard: the keystrokes still go to the window with the focus.

Just speculation, but I can't think of a better reason.

You might also consider Robin's suggestion to derive from wxPyControl
rather than wxPanel. I haven't tried it myself but I can't imagine him
suggesting it without good reason.

···

On Sun, 2003-01-05 at 08:17, Amos Joshua wrote:

Thanks alot! Thank you, Robin, too (also for the help with the
bitmap/transparency issue).

--
Cliff Wells <clifford.wells@attbi.com>