Just want to elaborate to what Justin have already brought up with his 
quote - there is significant difference between injecting event filters to 
Maya application vs. Maya main window.

Altering previous example provided by Marcus:

from PySide2 import QtCore
*from *maya.OpenMayaUI *import *MQtUtil
*from *shiboken2 *import *wrapInstance

class MyEventHandler(QtCore.QObject):
  def eventFilter(self, qobj, event):
    if event.type() == event.KeyPress:
      print("That's a keypress")
    return super(MyEventHandler, self).eventFilter(qobj, event)

handler = MyEventHandler()

app = QtCore.QCoreApplication.instance()
app.installEventFilter(handler)# app.removeEventFilter(handler)

mayaWindow = wrapInstance(int(MQtUtil.mainWindow()), QWidget)
mayaWindow.installEventFilter(handler)
*# mayaWindow.removeEventFilter(handler)*

Since QCoreApplication is somewhat level above all GUI objects it acts as 
an "overlord" in terms of events, so even if you have a widget that eats 
key press events QCoreApplication will still see it and it will invoke 
eventFilter method for the object that was installed as event filter. The 
implication of this is that whenever you type anything to any text field 
(QTextEdit, QLineEdit, etc.) that eventFilter will be invoked.

When installing the same event filter for Maya main window it will only be 
affected if none of the child widgets consumed event beforehand.

On Tuesday, March 3, 2020 at 3:04:40 PM UTC+1, Marcus Ottosson wrote:
>
> I remove the callback when my dialog window
>
> This is key. Even if your filter was incredibly slow, it’s fine IMO 
> because now it is apparent why it’s happening, and can be explicitly 
> disabled (by closing the window). Good that you pointed this out. Most 
> cases I’ve seen involved the filter being active at all times and that’s 
> the stuff that can start to add up. Especially as you accumulate tens to 
> hundreds of scripts at Maya startup over the course of a project.
>
> I think generally, if it doesn’t affect playback like in this case, global 
> event filters are harmless (and very useful). Most of the time though, if 
> possible, local event handlers like mouseMoveEvent is much preferable, 
> since it's only ever called for that one type of event.
>
> On Tue, 3 Mar 2020 at 14:01, <vaillant...@gmail.com <javascript:>> wrote:
>
>> Oh I see, both of you raised very valid points. It seems the event filter 
>> is called for every screen refresh. Indeed anything in that callback will 
>> have a very critical impact on the final framerate.
>> Putting a timer inside an empty event filter gives me between 0ms and 1ms 
>> (Well the time it takes to call time.time() twice).
>> Given that this trick is much like an evil 'global' variable, I agree 
>> that it will make things very hard to troubleshoot not to mentioned that 
>> this hack may blow out of proportion if everyone is using it like you 
>> mentioned.
>>
>> That being said, I think it fits my use case: I detect the 'SHIFT' key 
>> press event when I paint with a custom brush. The global event filter will 
>> only be 'slow' (~2-3ms tops) during a single press event of SHIFT and I 
>> remove the callback when my dialog window (used to configure the brush) is 
>> hidden. I haven't found any cleaner way to do this.
>>
>> For instance, overriding keyPressEvent in my dialog window won't work 
>> since I loose focus when painting. I use MEL artUserPaintCtx to setup my 
>> custom brush. In maya pressing SHIFT will switch your current brush mode to 
>> its smooth variant, unfortunately I can't find any callback related to this 
>> option.
>>
>> Thank you for your insight
>>
>> 2020年3月3日火曜日 19時14分56秒 UTC+9 Marcus Ottosson:
>>
>>> Simple way to test whether this affects your usecase is to just put a 
>>> timer inside of an empty event filter, installed onto the QApplication. I 
>>> expect you’ll find a non-zero percentage of CPU time being occupied by this 
>>> during simple tasks like mouse move, and for a much larger percentage to be 
>>> occupied during playback when the entire application is redrawn per frame - 
>>> guesstimating 2-5%.
>>>
>>> That, multiplied by the number of vendors that install event filters 
>>> onto the QApplication - your library, my library, two more libraries and so 
>>> forth - is IMO enough to avoid it if you can. Especially taken into account 
>>> that it is invisible to anyone but the author and very hard to debug. With 
>>> “My scene is slow” as a starting point, where does one go from there?
>>>
>>> And that’s not even considering what you *do* inside of the filter. I 
>>> saw a timeline annotation tool recently, using an event filter to update a 
>>> QPixmap whenever the timeline is redrawn. That’s rendering for 2-10 ms 
>>> depending on the frame range, and is a cost paid by everything happening on 
>>> draw, per frame, including animation rigs.
>>>
>>> But it’s true we should have a test case. Odds are this varies between 
>>> version of Maya, platform, maybe drivers and likely our perception and 
>>> circumstances (i.e. whether 10 ms per frame is anything to worry about or 
>>> not). If you do put something together @vaillant.rodolphe, it would be 
>>> great if you could post it here so we can move from guesstimating to 
>>> measuring.
>>>
>>> On Tue, 3 Mar 2020 at 08:43, Justin Israel <justin...@gmail.com> wrote:
>>>
>>>>
>>>>
>>>> On Tue, Mar 3, 2020, 8:35 PM <vaillant...@gmail.com> wrote:
>>>>
>>>>> Some additional reflection on the topic:
>>>>>
>>>>> Personally I don't notice any delay when filtering events from Maya's 
>>>>> main window (Maya 2019). 
>>>>> IMHO I'm not sure this is as big of an issue as you may think it is. I 
>>>>> need to test this more over time though. 
>>>>> Because my intution tells me events are usually very light and their 
>>>>> load stay the same regardless of the scene complexity,
>>>>> I'm really not sure why you would get noticable lag (even accounting 
>>>>> for python overhead)
>>>>>
>>>>
>>>> Well Qt does document a warning about possible performance implications 
>>>> of filtering every event in the application even from the C++ side of 
>>>> things:
>>>> https://doc.qt.io/archives/qt-4.8/eventsandfilters.html
>>>>
>>>> "It is also possible to filter all events for the entire application, 
>>>> by installing an event filter on the QApplication or QCoreApplication 
>>>> object. Such global event filters are called before the object-specific 
>>>> filters. This is very powerful, but it also slows down event delivery of 
>>>> every single event in the entire application; the other techniques 
>>>> discussed should generally be used instead."
>>>>
>>>> So it would be reasonable to assume it would be far slower to put a 
>>>> python function into the path of the main event loop that is catching 
>>>> every 
>>>> event in the app. That would be every paint event. Maybe could impact a 
>>>> large amount of redrawing in the app? 
>>>>
>>>>
>>>>> I haven't tried it yet but brave people might want to do event 
>>>>> filtering inside their C++ plugin:
>>>>>
>>>>> https://around-the-corner.typepad.com/adn/2012/09/access-the-qt-event-loop-in-maya.html
>>>>> Since we can access Maya Qt core application from there as well.
>>>>>
>>>>> #include <QtCore/QCoreApplication>
>>>>> QCoreApplication *app = qApp;
>>>>> void QObject::installEventFilter (QObject *filterObj)
>>>>>
>>>>>
>>>>> Cheers
>>>>>
>>>>>
>>>>> 2018年5月28日月曜日 21時57分54秒 UTC+9 Marcus Ottosson:
>>>>>>
>>>>>> Yes, this is possible.
>>>>>>
>>>>>> from PySide import QtGui, QtCore
>>>>>> class MyEventHandler(QtCore.QObject):
>>>>>>   def eventFilter(self, target, event):
>>>>>>     if event.type() == event.KeyPress:
>>>>>>       print("That's a keypress")
>>>>>>     return super(MyEventHandler, self).eventFilter(target, event)
>>>>>>
>>>>>> handler = MyEventHandler()
>>>>>>
>>>>>> app = QtGui.QApplication.instance()
>>>>>> app.installEventFilter(handler)# app.removeEventFilter(handler)
>>>>>>
>>>>>> That would normally be fine, *however* if there is one object where 
>>>>>> you never want a (Python) event filter, it would be the QApplication or 
>>>>>> Maya’s MainWindow. Because what happens is that *every single event* 
>>>>>> in Maya which was previously highly optimised C++ now has to pass 
>>>>>> through 
>>>>>> your Python function. Which means that even if your function does 
>>>>>> nothing 
>>>>>> but pass the event through, it still has a *significant* effect on 
>>>>>> performance. For starters, you should notice that with this filter 
>>>>>> installed, navigating in the viewport suddenly has a slight delay. As if 
>>>>>> the click caused a minor lag before eventually allowing you to dolly the 
>>>>>> camera.
>>>>>>
>>>>>> To put a picture in your head, here’s why.
>>>>>>
>>>>>> Information Super Highway
>>>>>>
>>>>>> --------------\                 /--------------->
>>>>>> -------------- \               /---------------->
>>>>>> ---------------->-------------/----------------->
>>>>>> -------------- /              \----------------->
>>>>>> --------------/                \---------------->
>>>>>>       C++           Python             C++
>>>>>>
>>>>>> Instead, what you should consider, if you are able, is installing an 
>>>>>> event filter *not* in QApplication or Maya’s main window, but in *your 
>>>>>> widget*.
>>>>>>
>>>>>> class MyWidget(QtGui.QDialog):
>>>>>>   def __init__(self, parent=None):
>>>>>>     super(MyWidget, self).__init__(parent)
>>>>>>
>>>>>> handler = MyEventHandler() 
>>>>>> mywidget = MyWidget()
>>>>>> mywidget.installEventFilter(handler)
>>>>>>
>>>>>> But *most* preferably, would be to not use an event filter, and 
>>>>>> instead override the event handler called only on keypress events 
>>>>>> <http://doc.qt.io/qt-5/qwidget.html#keyPressEvent>.
>>>>>>
>>>>>>   class MyWidget(QtGui.QDialog):
>>>>>>   def __init__(self, parent=None):
>>>>>>     super(MyWidget, self).__init__(parent)
>>>>>>
>>>>>>   def keyPressEvent(self, event):
>>>>>>     print("That's a press!")
>>>>>>     return super(MyWidget, self).keyPressEvent(event)
>>>>>>
>>>>>> That way, there is zero overhead on any event handling, other than 
>>>>>> the one you override.
>>>>>>
>>>>>> Hope it helps!
>>>>>> ​
>>>>>>
>>>>>> On 26 May 2018 at 07:27, Alexey Vasilyev <ole...@gmail.com> wrote:
>>>>>>
>>>>>>> Hi.
>>>>>>> I'm new to Maya programming.
>>>>>>> I'm curious if it's possible to track keypress events in Maya main 
>>>>>>> window using PySide or any other way?
>>>>>>> For example, when cube primitive is selected, I want to be able to 
>>>>>>> increase or decrease its subdivisions using Left and Right arrows. When 
>>>>>>> it's not selected, I want arrow keys to function in the default way.
>>>>>>> Thanks.
>>>>>>>
>>>>>>> -- 
>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>> Groups "Python Programming for Autodesk Maya" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>>> send an email to python_inside_maya+unsubscr...@googlegroups.com.
>>>>>>> To view this discussion on the web visit 
>>>>>>> https://groups.google.com/d/msgid/python_inside_maya/c7024d27-4a67-448e-9e57-a873ff85dcbc%40googlegroups.com
>>>>>>>  
>>>>>>> <https://groups.google.com/d/msgid/python_inside_maya/c7024d27-4a67-448e-9e57-a873ff85dcbc%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "Python Programming for Autodesk Maya" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to python_inside_maya+unsubscr...@googlegroups.com.
>>>>> To view this discussion on the web visit 
>>>>> https://groups.google.com/d/msgid/python_inside_maya/31a77359-f8e0-466d-8c68-ea826575cecb%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/python_inside_maya/31a77359-f8e0-466d-8c68-ea826575cecb%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Python Programming for Autodesk Maya" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to python_inside_maya+unsubscr...@googlegroups.com.
>>>> To view this discussion on the web visit 
>>>> https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA2m6NEVcLdt4x_HSViAmcOp8RaO%3D7Md14DUDmLwrp6L2Q%40mail.gmail.com
>>>>  
>>>> <https://groups.google.com/d/msgid/python_inside_maya/CAPGFgA2m6NEVcLdt4x_HSViAmcOp8RaO%3D7Md14DUDmLwrp6L2Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Python Programming for Autodesk Maya" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to python_inside_maya+unsubscr...@googlegroups.com <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/python_inside_maya/71e63b14-5402-495c-9d63-26b5f41b5650%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/python_inside_maya/71e63b14-5402-495c-9d63-26b5f41b5650%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to python_inside_maya+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/python_inside_maya/606a2648-4bfb-4432-9165-ae305064fa5ao%40googlegroups.com.

Reply via email to