emulating mouse wheel with FilterEvent

Hello,

I’m trying to implement a FIlterEvent to emulate mouse wheel when user holds shift or control
The trouble is that I can change the event type using:

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

however, I can’t set the wheel rotation value: I tried
event.WheelRotation=120 (which raises an Attibute error: can’t set attribute)
event.m_wheelRotation=120 (no error but event.GetWheelRotation returns 0)

In the same time, I can modify event.X and event.Y with no difficulties…
I attached a minimal exemple.

Any Ideas how to solve my problem?
Thanks in advance

MouseWheelEmulation.py (1.65 KB)

Hello again,

Forgot to mention

wx.version()=3.0.0.0 msw (classic)

Le vendredi 2 octobre 2015 09:32:39 UTC+2, Yves Le Feuvre a écrit :

···

Hello,

I’m trying to implement a FIlterEvent to emulate mouse wheel when user holds shift or control
The trouble is that I can change the event type using:

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

however, I can’t set the wheel rotation value: I tried
event.WheelRotation=120 (which raises an Attibute error: can’t set attribute)
event.m_wheelRotation=120 (no error but event.GetWheelRotation returns 0)

In the same time, I can modify event.X and event.Y with no difficulties…
I attached a minimal exemple.

Any Ideas how to solve my problem?
Thanks in advance

My guess is that you are not running the source code you think you
are. Like, for example, you aren’t really saving the changed
source.
On Windows, your code works just fine. Your call to set event.X
fails with a “can’t set attribute” error, but if I set
m_wheelRotation and m_x, both changes take effect.
if event.ControlDown():
print event.GetWheelRotation()
event.SetEventType(wx.wxEVT_MOUSEWHEEL)
event.m_wheelRotation=120
event.m_x=1234
print event.WheelRotation
print event.GetWheelRotation()
print event.X
print event.GetX()
That prints
C:\tmp>

···

Yves Le Feuvre wrote:

    I'm trying to implement a FIlterEvent to emulate mouse wheel

when user holds shift or control

    The trouble is that I can change the event type using:



    event.SetEventType(wx.wxEVT_MOUSEWHEEL)



    however, I can't set the wheel rotation value: I tried

    event.WheelRotation=120            (which raises an Attibute

error: can’t set attribute)

    event.m_wheelRotation=120         (no error but

event.GetWheelRotation returns 0)

    In the same time, I can modify event.X and event.Y with no

difficulties…

    I attached a minimal exemple.

`C:\tmp>py -2 MouseWheelEmulation.py``

  ``0``

  ``120``

  ``120``

  ``1234``

  ``1234``

  ``Received mouse wheel event 120 1234`
-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

Yves Le Feuvre wrote:

Hello again,

Forgot to mention

wx.version()=3.0.0.0 msw (classic)

OK, I didn't see this at first. My example was on 2.8.12.1
(msw-unicode) If I try it with 3.0.3.dev78327 msw (phoenix), then I see
your results.

Interestingly, in 3.0.3, event.X doesn't work any more -- it has to be
event.x. Changing it has no effect, but calling SetX works. However,
there is no SetWheelRotation method. I'm guessing this interface is
simply still in flux.

Also, wx.App.SetCallFilterEvent is not implemented; it always calls the
filter.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Thanks for your answer,

So, it sounds there is only little chance to get both a cross platform a and cross version solution?

(my soft runs on win, OSX and linux)

any workaround (beside testing for shift and control key in OnLeftMouseDown() event handler?)

Yves

Le vendredi 2 octobre 2015 09:32:39 UTC+2, Yves Le Feuvre a écrit :

···

Hello,

I’m trying to implement a FIlterEvent to emulate mouse wheel when user holds shift or control
The trouble is that I can change the event type using:

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

however, I can’t set the wheel rotation value: I tried
event.WheelRotation=120 (which raises an Attibute error: can’t set attribute)
event.m_wheelRotation=120 (no error but event.GetWheelRotation returns 0)

In the same time, I can modify event.X and event.Y with no difficulties…
I attached a minimal exemple.

Any Ideas how to solve my problem?
Thanks in advance

Yves Le Feuvre wrote:

So, it sounds there is only little chance to get both a cross platform
a and cross version solution?
(my soft runs on win, OSX and linux)

Well, you are using version 3.0.0.0 of wxPython. The first release of
ANY product is going to have some unsolved issues. Do you HAVE to use 3.0?

Someone on the order of Robin is going to have to speak to these
differences. I don't know whether the behavior is intentional or
accidental, although I suspect it is accidental.

any workaround (beside testing for shift and control key in
OnLeftMouseDown() event handler?)

That is the alternative I would suggest for now. Do it in
OnLeftMouseDown and generate a new wheel event from scratch. It's less
overhead than the filter solution.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Hi,
first, I confirm that the previously described behavior

(event.WheelRotation=120 ->AttributeError: can’t set attibute)
is observed with versions 3.0.0.0 on MS windows, macOSX (cocoa), but not on 2.8.12.0 gtk (linux version)

On linux, I can set m_wheelRotation as mentioned in your post

So the trick to get it work with version 3.0 (at least on my mac, I don’t have my windows machine here) is to use monkey patching, testing either wx.version() or the presence of m_wheelRotation attribute

def FilterEvent(self,event):

if not hasattr(self, “WheelFunc”): # if it does not exist

self.WheelFunc=wx.MouseEvent.GetWheelRotation # preserve original GetWheelRotation method

setattr(wx.MouseEvent, ‘GetWheelRotation’, self.WheelFunc) # restore normal wheel behavior

if event.GetEventType()==wx.wxEVT_LEFT_DOWN:

if event.ControlDown():

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

if wx.VERSION_STRING>=“3.0.0.0”:

#if not hasattr(event,‘m_wheelRotation’):

setattr(wx.MouseEvent, ‘GetWheelRotation’, lambda(x):120)

else:

event.m_wheelRotation=120

elif event.ShiftDown():

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

if wx.VERSION_STRING>=“3.0.0.0”:

#if not hasattr(event,‘m_wheelRotation’):

setattr(wx.MouseEvent, ‘GetWheelRotation’, lambda(x):-120)

else:

event.m_wheelRotation=-120

However,

  1. I don’t understand why monkey patching does not work on wx.version()=2.8.12.0…

  2. I guess it would be nicer (less ugly) to use instance monkey patching instead of class monkey patching, but I couldn’t manage to get it work

Thanks anyway for your help!

Le vendredi 2 octobre 2015 09:32:39 UTC+2, Yves Le Feuvre a écrit :

···

Hello,

I’m trying to implement a FIlterEvent to emulate mouse wheel when user holds shift or control
The trouble is that I can change the event type using:

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

however, I can’t set the wheel rotation value: I tried
event.WheelRotation=120 (which raises an Attibute error: can’t set attribute)
event.m_wheelRotation=120 (no error but event.GetWheelRotation returns 0)

In the same time, I can modify event.X and event.Y with no difficulties…
I attached a minimal exemple.

Any Ideas how to solve my problem?
Thanks in advance

That is one of the worst hack jobs I’ve ever encountered. Remember
that you have the full source code available. SURELY it would be
better for you to expend a little energy into figuring out WHY the
old model doesn’t work, rather than foisting something like this on
your unsuspecting users.

···

Yves Le Feuvre wrote:

    So the trick to get it work with version 3.0 (at

least on my mac, I don’t have my windows machine here) is to use
monkey patching, testing either wx.version() or the presence of
m_wheelRotation attribute

def FilterEvent(self,event):

if not hasattr(self, “WheelFunc”): #
if it does not exist

self.WheelFunc=wx.MouseEvent.GetWheelRotation #
preserve original GetWheelRotation method

        setattr(wx.MouseEvent, 'GetWheelRotation',

self.WheelFunc) #
restore normal wheel behavior

if event.GetEventType()==wx.wxEVT_LEFT_DOWN:

if event.ControlDown():

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

if wx.VERSION_STRING>=“3.0.0.0”:

        #if not

hasattr(event,‘m_wheelRotation’):

        setattr(wx.MouseEvent,

‘GetWheelRotation’, lambda(x):120)

-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

I’ll give a look at the source code of wxPython, however, at first look, it looks much too complicate for a hobbyist programmer like me (don’t know anything about SWIG, …).
Moreover, although my software is not intended to be broadly distributed, I can’t be sure of the wxPython version that will be installed on final user machines. correcting the wxPython source code is definitely the way to go, but my small and very ugly hack does the job for other versions.

and I’m sure I can write even worse hacks, unintentionally :slight_smile:

Le vendredi 2 octobre 2015 09:32:39 UTC+2, Yves Le Feuvre a écrit :

···

Hello,

I’m trying to implement a FIlterEvent to emulate mouse wheel when user holds shift or control
The trouble is that I can change the event type using:

event.SetEventType(wx.wxEVT_MOUSEWHEEL)

however, I can’t set the wheel rotation value: I tried
event.WheelRotation=120 (which raises an Attibute error: can’t set attribute)
event.m_wheelRotation=120 (no error but event.GetWheelRotation returns 0)

In the same time, I can modify event.X and event.Y with no difficulties…
I attached a minimal exemple.

Any Ideas how to solve my problem?
Thanks in advance