Search code examples
c++qtuser-interfaceqt-events

Disable KeyEvent for "unneeded QWidget?


I have a QDockWidget in my Mainwindow with a QTableWidget and two QPushbuttons. Of course, I can click the buttons with my mouse, but I want also to "click" them with left- and right-arrow-key.

It nearly works perfect. But before they are clicked via key, it seems like the focus jumps to the right/left of the QTableWidget (the items in it, it goes through all columns).

Is it possible that I have the KeyPressEvents only for the buttons in the QDockWidget?


Solution

  • You can use an event filter like this:

    class Filter : public QObject
    {
    public:
        bool eventFilter(QObject * o, QEvent * e)
        {
            if(e->type() == QEvent::KeyPress)
            {
                QKeyEvent * event = static_cast<QKeyEvent *>(e);
                if((event->key() == Qt::Key_Left) || (event->key() == Qt::Key_Right))
                {
                    //do what you want ...
                    return true;
                }
            }
            return QObject::eventFilter(o, e);
        }
    };
    

    keep an instance of the filter class in your main window class:

    private:
        Filter filter;
    

    then install it in your widgets, e.g. in your main window class constructor:

    //...
    installEventFilter(&filter); //in the main window itself
    ui->dockWidget->installEventFilter(&filter);
    ui->tableWidget->installEventFilter(&filter);
    ui->pushButton->installEventFilter(&filter);
    //etc ...
    

    You may want to check for modifiers (e.g. Ctrl key), to preserve the standard behaviour of the arrow keys:

    //...
    if(event->modifiers() == Qt::CTRL) //Ctrl key is also pressed
    {
            if((event->key() == Qt::Key_Left) || (event->key() == Qt::Key_Right))
            {
    
    //...