RemoveEventFilters() (Without specifying the object.)



  • Is there a known good way to remove all event filters installed on an object without having to specify the event filter itself? How about just the last installed event filter?

    (If possible, it would be nice if the classes that need to remove them not need to be cognizant of the wide varieties of event filters that may have been installed. I suppose I could subclass QObject, but I think this unravels into having to rebuild the library with other relevant descendants inheriting from MyQObject instead of QObject.)


  • Lifetime Qt Champion

    Hi,

    AFAIK, no. If you want to modify the event filters on the fly you'll have to somehow keep a trace of them in e.g. a QMap



  • OK, Thanks. Since it is not available, I think I will try creating a general function that takes the filter type as an input (maybe in conjunction with some design pattern if necessary).


  • Lifetime Qt Champion

    Depending on your needs you could write a filter manager that will keep track on the installed filter from an object or even a more generic class that manages filters for objects.



  • I think what I've done is similar to your suggestions.

    (The class I created takes generic pointers to QObjects, which are really specialty filters, and stores the pointers to the QObjects alongside pointers to the objects on which they are installed. Since removeEventFilter takes a generic QObject pointer, I do not have to track the specific filter type to later remove it as long as I keep track of which QObject pointers were installed on which objects.)

    I do not yet have a clean build; however, I am expecting it to work and it turned out to be fairly simple to implement.


  • Lifetime Qt Champion

    Sounds good :)

    Happy coding !



  • You do not need any additional tracking.

    1. register your custom event type .registerEventType for your own event type
      lets call it RemoveEventFilter

    2. In all your bool MyClass::eventFilter ( QObject * watched, QEvent * event )
      check if event is of you custom type and
      call removeEventFilter(watched ) from there .

    3. Now all you need to do to remove all event filters for specific object;

    • create RemoveEventFilter event
    • call bool QCoreApplication::sendEvent ( QObject * receiver, QEvent * event )
      for object you want


  • I think I understand.

    To make sure, let me rephrase it a bit as I understand it:

    1. Create a new custom event type called RemoveEventFilters

    (I made it plural since it should remove all relevant event filters, right?)

    1. Add an entry to all my eventFilter overrides that "listens" for this event.

    2. send the RemoveEventFilters event to the object for which I want all event filters removed:
      @
      QCoreApplication::sendEvent ( QObject *receiver, QEvent *event)

    @
    (In the line above event is the newly created RemoveEventFilters event.)

    1. Upon seeing the remove event filter event, the object will look through a list of the type of events I would like to remove and iteratively remove them:

    @ foreach(e, eventTypeList)
    removeEventFilter(e);
    @

    Is that what you are suggesting?

    If so, I think that would work as well, and would have both advantages and disadvantages as versus my current implementation.

    Thank you for sharing your idea.



  • I guess I could also just add the foreach code above as a seperate method, and just call that method to remove them, so as to not pollute its event processing loop. If I understand correctly, one disadvantage to this type of approach is that removeEventFilter will be called unnecessarily for any of the event filter types that are not installed, but one advantage is that it will not have to track the installed events.



    1. seems wrong.
      QObject::eventFilter already filters events if this object has been installed as an event filter for the watched object.

    This means if you received event in filter and it is event type you registered
    just remove this event filter from watched object.

    @MyClass::eventFilter ( QObject * watched, QEvent * event )
    {
    if( event->type() == RemoveEventFilters_Type )
    watched->removeEventFilter ( this );

    }@



  • Got it. It does still have the disadvantage of requiring all my event filters to have:

    @
    if( event->type() == RemoveEventFilters_Type )
    watched->removeEventFilter ( this );
    @

    It also uses the event loop, which I would expect to be substantially slower (although not noticeably for my needs).

    Notwithstanding, leveraging the fact it is already processing events is a very cool and elegant way to solve the problem and algorithmically even simpler than what I currently have. Thank you very much for sharing.


  • Lifetime Qt Champion

    You can put that in a "filter base class" from which you derive all your filters and in every eventFilter you call the base class implementation that will do that when not handling the event in your subclass



  • Yes, that's true, and I do have already have that base class. Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.