Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. using QKeyEvents
Forum Updated to NodeBB v4.3 + New Features

using QKeyEvents

Scheduled Pinned Locked Moved Solved General and Desktop
40 Posts 4 Posters 4.8k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mzimmersM Online
    mzimmersM Online
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I'm experimenting with handling key events in an app, and (as usual) I'm having beginner's difficulties. I've read a couple pages on this, and there seems to be a few different ways to do it. I chose one that made the most sense to me.

    I created a KeyPress class:

    class KeyPress : public QWidget
    {
        Q_OBJECT
    public:
        explicit KeyPress(QWidget *parent = nullptr);
    protected:
        void keyPressEvent (QKeyEvent *ev);
        void keyReleaseEvent(QKeyEvent *ev);
    
    signals:
        void keyEvent(int event, int key);
    };
    

    And in my main widget, I do this in the c'tor:

        // create and connect a KeyPress object.
        m_keyPress = new KeyPress(this);
        connect(m_keyPress, &KeyPress::keyEvent, this, &Widget::handleKeyEvent);
        m_keyPress->installEventFilter(this);
    

    And I overrode the event filter:

    bool eventFilter(QObject *obj, QEvent *ev) override;
    ...
    bool Widget::eventFilter(QObject *obj, QEvent *ev)
    {
        bool rc = false;
    
        if (obj == m_keyPress)
        {
            if (ev->type() == QEvent::KeyPress)
            {
                rc = true;
                qDebug() << ev;
            }
        }
        return rc;
    }
    

    I realize this isn't functional yet, but I thought I'd at least catch a key press. I'm not, though. Can someone tell me what I'm missing?

    Thanks...

    1 Reply Last reply
    0
    • gde23G Offline
      gde23G Offline
      gde23
      wrote on last edited by
      #2

      Why do you need the KeyEvent Class?

      You can do following:

      Subclass the widget where you want the keyevents to be catched.
      Then add a definition for

      void YourWidget::keyPressEvent(QKeyEvent *event)
      

      that looks something like this:

      void YourWidget::keyPressEvent(QKeyEvent *event)
      {
          if(event->key() == Qt::Key_A)
          {
              doAKeyPressStuff();
          }
          else
          {
              doAnyOtherKeyPressStuff();
          }
      }
      
      mzimmersM 1 Reply Last reply
      0
      • gde23G gde23

        Why do you need the KeyEvent Class?

        You can do following:

        Subclass the widget where you want the keyevents to be catched.
        Then add a definition for

        void YourWidget::keyPressEvent(QKeyEvent *event)
        

        that looks something like this:

        void YourWidget::keyPressEvent(QKeyEvent *event)
        {
            if(event->key() == Qt::Key_A)
            {
                doAKeyPressStuff();
            }
            else
            {
                doAnyOtherKeyPressStuff();
            }
        }
        
        mzimmersM Online
        mzimmersM Online
        mzimmers
        wrote on last edited by
        #3

        @gde23 I guess I don't understand the reason for the subclass. I want to trap a key press anywhere on my main widget. I don't want sub-class my main widget, do I?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          It's the other way around, you need to install KeyPress in your QMainWindow.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          mzimmersM 1 Reply Last reply
          1
          • SGaistS SGaist

            Hi,

            It's the other way around, you need to install KeyPress in your QMainWindow.

            mzimmersM Online
            mzimmersM Online
            mzimmers
            wrote on last edited by
            #5

            @SGaist not using QMainWindow; using QWidget.

            class Widget : public QWidget
            {
                Q_OBJECT
            ...
            

            Same thing, though?

            And by "install KeyPress" I assume you mean more than create an object of that class, since I'm already doing that.

                m_keyPress = new KeyPress(this);
                connect(m_keyPress, &KeyPress::keyEvent, this, &Widget::handleKeyEvent);
                m_keyPress->installEventFilter(this);
            

            I'm missing a step here, aren't I?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by SGaist
              #6

              You're not missing a step, you are doing one in the wrong direction. The object on the left of installEventFilter is the one that is going to be monitored so just call

              installEventFilter(m_keyPress);
              

              See the installEventFilter documentation.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • mzimmersM Online
                mzimmersM Online
                mzimmers
                wrote on last edited by
                #7

                OK...made that change; still not seeing what I expect.

                    // create and connect a KeyPress object.
                    m_keyPress = new KeyPress(this);
                    connect(m_keyPress, &KeyPress::keyEvent, this, &Widget::handleKeyEvent);
                    installEventFilter(m_keyPress);
                

                Here's my event routine:

                void KeyPress::keyPressEvent(QKeyEvent *ev)
                {
                    int key;
                
                    key = ev->key();
                    if (key == Qt::Key_Alt)
                    {
                        emit keyEvent(QEvent::KeyPress, key);
                    }
                }
                

                I'm never hitting a breakpoint in there.

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Because an event filter re-implements the eventFilter method and does all there. It does not replace a class original methods.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  mzimmersM 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    Because an event filter re-implements the eventFilter method and does all there. It does not replace a class original methods.

                    mzimmersM Online
                    mzimmersM Online
                    mzimmers
                    wrote on last edited by
                    #9

                    @SGaist said in using QKeyEvents:

                    Because an event filter re-implements the eventFilter method and does all there. It does not replace a class original methods.

                    So, which object needs the eventFilter() method? I've tried adding to both the Widget and the KeyPress -- both compile and run, but neither trigger a breakpoint.

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Did you check the example I linked to ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      mzimmersM 1 Reply Last reply
                      1
                      • SGaistS SGaist

                        Did you check the example I linked to ?

                        mzimmersM Online
                        mzimmersM Online
                        mzimmers
                        wrote on last edited by
                        #11

                        @SGaist you're referring to the KeyPressEater class in the QObject::installEventFilter() documentation, right?

                        Its behavior isn't the same as my KeyPress class, but I can worry about that later. I still don't see why I'm not hitting a breakpoint.

                        bool KeyPress::eventFilter(QObject *obj, QEvent *ev)
                        {
                            bool rc = false;
                        
                            if (ev->type() == QEvent::KeyPress)
                            {
                                if (obj == this)
                                {
                                    rc = true;
                                    qDebug() << ev;
                                }
                            }
                            return rc;
                        }
                        

                        My breakpoint is on my inner "if" and it's never reached.

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          Because as is, your filter will never be the target of a KeyPress event.
                          The value of obj will be one of the object you installed your filter on.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0
                          • mzimmersM Online
                            mzimmersM Online
                            mzimmers
                            wrote on last edited by
                            #13

                            I understand your 2nd statement, but not the first. I install the filter on my Widget object. Is a QWidget incapable of accepting KeyPress events?

                            1 Reply Last reply
                            0
                            • mzimmersM Online
                              mzimmersM Online
                              mzimmers
                              wrote on last edited by
                              #14

                              Well, I got it partly working -- the problem was that I was deriving my KeyPress class from QWidget instead of QObject.

                              Now, though, my filter only seems to be trapping "meta keys." Control, alt, etc. all work, but regular keys like A, B, C don't. It appears that these keys generate a ShortcutOverride event. Does this make sense to you?

                              Thanks...

                              1 Reply Last reply
                              0
                              • mzimmersM Online
                                mzimmersM Online
                                mzimmers
                                wrote on last edited by
                                #15

                                My filter seems to be doing what I want (when two keys are held down, I make a button visible).

                                    if (C_pressed && D_pressed)
                                    {
                                        ui->pushButtonNics->setVisible(true);
                                    }
                                    else
                                    {
                                        ui->pushButtonNics->setVisible(false);
                                    }
                                

                                But when I click on that button, my clicked slot isn't reached. I thought maybe holding down the keys was blocking the button push, but my other buttons work fine. My button is enabled when visible (I checked in the debugger). Any ideas why it's not generating the signal?

                                Thanks...

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  You are forgetting to call the base class implementation.

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  mzimmersM 1 Reply Last reply
                                  0
                                  • SGaistS SGaist

                                    You are forgetting to call the base class implementation.

                                    mzimmersM Online
                                    mzimmersM Online
                                    mzimmers
                                    wrote on last edited by
                                    #17

                                    @SGaist I hadn't forgotten; I just hadn't gotten to that yet. But shouldn't I hit this slot anyway?

                                    void Widget::on_pushButtonNics_clicked()
                                    {
                                        qDebug() << "Nics pressed.";
                                    }
                                    
                                    1 Reply Last reply
                                    0
                                    • SGaistS Offline
                                      SGaistS Offline
                                      SGaist
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #18

                                      The last implementation I saw does not call it at all which means that all events are filtered out.

                                      To check, comment out the filter installation and see if it does work correctly.

                                      Interested in AI ? www.idiap.ch
                                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                      mzimmersM 1 Reply Last reply
                                      0
                                      • SGaistS SGaist

                                        The last implementation I saw does not call it at all which means that all events are filtered out.

                                        To check, comment out the filter installation and see if it does work correctly.

                                        mzimmersM Online
                                        mzimmersM Online
                                        mzimmers
                                        wrote on last edited by
                                        #19

                                        @SGaist let's make sure we're talking about the same thing. Here's where I create the filter:

                                            // create and connect a KeyPress object.
                                            m_keyPress = new KeyPress(this);
                                            connect(m_keyPress, &KeyPress::keyEvent, this, &Widget::handleKeyEvent);
                                            installEventFilter(m_keyPress);
                                        
                                            // hide the button for the NICs window.
                                        //    ui->pushButtonNics->setVisible(false);
                                        

                                        You'll notice that the last line is commented out. And, it works. So it would seem that it has something to do with the filter...?

                                        1 Reply Last reply
                                        0
                                        • SGaistS Offline
                                          SGaistS Offline
                                          SGaist
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #20

                                          Can you provide a minimal compilable example that shows the behaviour ?
                                          Si au can check on my side what is going on.

                                          Interested in AI ? www.idiap.ch
                                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                          mzimmersM 1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved