Search code examples
c++qtqt4

How to stop spacebar from triggering a focused QPushButton?


Suppose I have a focused QPushButton:

my_button = new QPushButton("Press me!", this);
my_button->setFocus();

When this button is displayed, pressing Space will trigger (i.e. click) the button. I don't want this behavior. Instead, I would like Ctrl+Enter to trigger the button.

How can I achieve this in Qt?

(Working examples would really help as this is part of my first Qt app)


Solution

  • I think the best way is to do as @thuga said. The idea is to subclass the QPushButton and reimplement keyPressEvent().

    This may look as follows:

    .h

    #include <QPushButton>
    
    class MyQPushButton final : public QPushButton
    {
        Q_OBJECT
    
        public:
            MyQPushButton(const QIcon icon, const QString & text, QWidget * parent = nullptr);
            MyQPushButton(const QString & text, QWidget * parent = nullptr);
            MyQPushButton(QWidget * parent = nullptr);
    
        protected:
            void keyPressEvent(QKeyEvent * e) override;
    };
    

    .cpp

    #include <QKeyEvent>
    
    MyQPushButton::MyQPushButton(const QIcon icon, const QString & text, QWidget * parent) : QPushButton(icon, text, parent)
    {}
    MyQPushButton::MyQPushButton(const QString & text, QWidget * parent) : QPushButton(text, parent)
    {}
    MyQPushButton::MyQPushButton(QWidget * parent) : QPushButton(parent)
    {}
    
    void MyQPushButton::keyPressEvent(QKeyEvent * e)
    {
        if(e->key() == Qt::Key_Return && (e->modifiers() & Qt::ControlModifier))
            click();
        else
            e->ignore();
    }
    

    This way, the Space event is not handled anymore and the Ctrl + Enter will run the click() function.
    I have tested it and it worked successfully.

    I've written this example as simple as possible. Of course, feel free to adapt it to best fit your needs.


    If you want it to work with the numpad Enter key too, you can catch Qt::Key_Enter too. The if condition would be something like:

    if((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && (e->modifiers() & Qt::ControlModifier))