Search code examples
c++qtwinapiqeventqeventloop

Managing keyboard events between Win32 app and QWinMigrate


I have integrated a Qt dialog into a traditional Win32 application, and am now a bit stumped on how to manage the keyboard events propagating from Qt->Win32. Is there any way test if Qt is 'handling' events (eg, input going to an editbox), and prevent these events propagating to the host application?

The Win32 application has its own very-complex accelerator system, and when working with native editboxes generally we disable accelerators manually. I donb't have the ability to do this for the Qt dialog, as its a shared widget amongst several applications.

Currently I disable the hosts accelerators on the dialog as a whole gaining focus, but would it be possible to tell Qt to prevent kbd events from editboxes from propagating? Ideally without modifying the QtDialogs code (although I can do that if necessary?)


Solution

  • I have no idea if this will actually work but you might give this a go:

    class KeyEventPropagetionPreventer: public QObject
    {
    public:
        KeyEventPropagetionPreventer( QWidget * widget ) 
        : QObject( widget ), widget( widget ), instercept_events( true )
        {
            widget->installEventFilter( this )
        }
    
        bool eventFilter(QObject *obj, QEvent *event)
        {
            if ( intercept_events && event->type() == QEvent::KeyPress) // or other types if needed
            {
                intercept_events = false; // prevents eating your own events
                QKeyEvent new_event( *event ); // Might be that you need to implement your own copying function if the copyconstructor is disabled
                QApplication::sendEvent(this->widget, &new_event);
                instercept_events = true;
                return true;
            } 
            else 
            {
                return QObject::eventFilter(obj, event);
            }
        }
    
    private:
        QWidget * widget;
        bool instercept_events;
    }
    

    Then you add this line where you create the dialog:

    new KeyEventPropagetionPreventer( your_qt_dialog ); // will be deleted by the Qt parent/child system when the dialog is deleted.
    

    The idea is to intercept all Keyboard events, but then also create a copy of it and send that to the widget. Hopefully the intercepting actually prevents the event from propagating (and is not qt-eventsystem-only or something) and the QApplication::sendEvent() does not propagate itself.

    I hope this works, good luck!

    (ps. This code has not been tested or compiled)