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
QtWS25 Last Chance

using QKeyEvents

Scheduled Pinned Locked Moved Solved General and Desktop
40 Posts 4 Posters 4.7k Views
  • 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.
  • S SGaist
    8 May 2020, 15:54

    You are forgetting to call the base class implementation.

    M Offline
    M Offline
    mzimmers
    wrote on 8 May 2020, 16:09 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
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 8 May 2020, 18:00 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

      M 1 Reply Last reply 8 May 2020, 18:06
      0
      • S SGaist
        8 May 2020, 18:00

        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.

        M Offline
        M Offline
        mzimmers
        wrote on 8 May 2020, 18:06 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
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 8 May 2020, 18:12 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

          M 1 Reply Last reply 8 May 2020, 18:16
          0
          • S SGaist
            8 May 2020, 18:12

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

            M Offline
            M Offline
            mzimmers
            wrote on 8 May 2020, 18:16 last edited by
            #21

            @SGaist

            keypress.h

            #ifndef KEYPRESS_H
            #define KEYPRESS_H
            
            #include <QWidget>
            #include <QtGui>
            
            class KeyPress : public QObject
            {
                Q_OBJECT
            public:
                explicit KeyPress(QWidget *parent = nullptr);
            protected:
                bool eventFilter(QObject *obj, QEvent *ev) override;
            
            signals:
                void keyEvent(QEvent event, int key);
            };
            
            #endif // KEYPRESS_H
            

            keypress.cpp

            #include "keypress.h"
            
            KeyPress::KeyPress(QWidget *parent) : QObject (parent)
            {
            }
            
            bool KeyPress::eventFilter(QObject *obj, QEvent *ev)
            {
                Q_UNUSED(obj)
            
                bool rc = false;
                int key;
                QKeyEvent *qke;
            
                if (ev->type() == QEvent::ShortcutOverride || ev->type() == QEvent::KeyRelease)
                {
                    qke = static_cast<QKeyEvent *>(ev);
                    key = qke->key();
            
                    // don't bother signaling when the key isn't meaningful to us.
                    if (key == 'c' || key == 'C' || key == 'd' || key == 'D')
                    {
                        emit keyEvent(*ev, key);
                    }
                    rc = true;
                }
                else
                {
                    rc = QObject::eventFilter(obj, ev);
                }
                return rc;
            }
            

            Let me know if there's something more you want to look at...thanks.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 8 May 2020, 18:30 last edited by
              #22

              A minimal widget that you install that filter on would be nice :-)

              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
              • M Offline
                M Offline
                mzimmers
                wrote on 8 May 2020, 19:03 last edited by
                #23

                widget.h

                #ifndef WIDGET_H
                #define WIDGET_H
                
                #include <QWidget>
                #include "keypress.h"
                
                namespace Ui {
                    class Widget;
                }
                
                class Widget : public QWidget
                {
                    Q_OBJECT
                
                private:
                    Ui::Widget *ui;
                    KeyPress *m_keyPress = nullptr;
                    bool C_pressed = false;
                    bool D_pressed = false;
                
                public:
                    explicit Widget(QWidget *parent = nullptr);
                    ~Widget();
                private slots:
                    void on_pushButtonQuit_clicked();
                    void on_pushButtonNics_clicked();
                    void handleKeyEvent(QEvent event, int key);
                signals:
                    void quitButtonPushed(int rc);
                };
                #endif // WIDGET_H
                
                

                widget.cpp

                #include <iostream>
                #include <sstream>
                #include <stdio.h>
                
                #include <QDebug>
                
                #include "editdialog.h"
                #include "nics.h"
                #include "widget.h"
                #include "ui_widget.h"
                
                using namespace std;
                
                Widget::Widget(QWidget *parent) :
                    QWidget(parent),
                    ui(new Ui::Widget)
                {
                    ui->setupUi(this);
                
                    // 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);
                }
                
                Widget::~Widget()
                {
                    delete ui;
                }
                
                
                void Widget::on_pushButtonQuit_clicked()
                {
                    emit quitButtonPushed(0);
                }
                
                void Widget::handleKeyEvent(QEvent event, int key)
                {
                    if (event.type() == QEvent::ShortcutOverride)
                    {
                        if (key == 'c' || key == 'C')
                        {
                            C_pressed = true;
                        }
                        else if ((key == 'd' || key == 'D'))
                        {
                            D_pressed = true;
                        }
                
                    }
                    else if (event.type() == QEvent::KeyRelease)
                    {
                        if (key == 'c' || key == 'C')
                        {
                            C_pressed = false;
                        }
                        else if ((key == 'd' || key == 'D'))
                        {
                            D_pressed = false;
                        }
                    }
                
                    if (C_pressed && D_pressed)
                    {
                        ui->pushButtonNics->setVisible(true);
                    }
                    else
                    {
                        ui->pushButtonNics->setVisible(false);
                    }
                }
                
                
                
                void Widget::on_pushButtonNics_clicked()
                {
                    Nics nics(this);
                    nics.exec();
                }
                

                You'll want to connect the Widget signal to something. Sorry...this was as compact as I dared make it.

                Thanks for looking at this.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 8 May 2020, 21:05 last edited by
                  #24

                  Since I don't have the .ui file I modified the code a bit.

                  I created a QPushButton and did an explicit connection and it worked was expected.

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

                  M 1 Reply Last reply 8 May 2020, 21:07
                  0
                  • S SGaist
                    8 May 2020, 21:05

                    Since I don't have the .ui file I modified the code a bit.

                    I created a QPushButton and did an explicit connection and it worked was expected.

                    M Offline
                    M Offline
                    mzimmers
                    wrote on 8 May 2020, 21:07 last edited by
                    #25

                    @SGaist well, doesn't that tear the rag right off the bush.

                    What exactly did you mean by "explicit" connection?

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 9 May 2020, 11:41 last edited by
                      #26

                      By explicit I meant writing the connect statement. Currently you are using the connectSlotsByName feature that is called as part of setupUi.

                      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
                      • M Offline
                        M Offline
                        mzimmers
                        wrote on 9 May 2020, 13:11 last edited by
                        #27

                        OK...I added the explicit connection in widget.cpp:

                            connect(ui->pushButtonNics, &QPushButton::clicked, this, &Widget::on_pushButtonNics_clicked);
                        

                        Here's my widget.ui:

                        <?xml version="1.0" encoding="UTF-8"?>
                        <ui version="4.0">
                         <class>Widget</class>
                         <widget class="QWidget" name="Widget">
                          <property name="geometry">
                           <rect>
                            <x>0</x>
                            <y>0</y>
                            <width>320</width>
                            <height>160</height>
                           </rect>
                          </property>
                          <property name="sizePolicy">
                           <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
                            <horstretch>0</horstretch>
                            <verstretch>0</verstretch>
                           </sizepolicy>
                          </property>
                          <property name="minimumSize">
                           <size>
                            <width>320</width>
                            <height>160</height>
                           </size>
                          </property>
                          <property name="windowTitle">
                           <string>Discovery Utility</string>
                          </property>
                          <widget class="QPushButton" name="pushButtonNics">
                           <property name="geometry">
                            <rect>
                             <x>130</x>
                             <y>50</y>
                             <width>75</width>
                             <height>23</height>
                            </rect>
                           </property>
                           <property name="text">
                            <string>NICs</string>
                           </property>
                          </widget>
                         </widget>
                         <layoutdefault spacing="6" margin="11"/>
                         <resources/>
                         <connections/>
                        </ui>
                        

                        And, just for good measure, here's main.cpp:

                        #include <QApplication>
                        
                        #include <stdio.h>
                        
                        #include "widget.h"
                        
                        using namespace std;
                        
                        int main(int argc, char *argv[])
                        {
                            int rc;
                            QApplication a(argc, argv);
                            Widget *widget;
                        
                            widget = new Widget();
                            widget->show();
                            rc = a.exec();
                            return rc;
                        }
                        

                        This is my entire project, except for the pro file itself:

                        QT       += core gui network serialport xml
                        
                        greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
                        
                        TARGET = discovery_utility_test
                        DEFINES += QT_DEPRECATED_WARNINGS
                        SOURCES += \
                        	keypress.cpp \
                        	main.cpp \
                        	nics.cpp \
                        	widget.cpp
                        
                        HEADERS += \
                        	keypress.h \
                        	nics.h \
                        	widget.h \
                        
                        FORMS += \
                        	nics.ui \
                        	widget.ui
                        

                        Could it possibly be due to the way that I'm building it? Or, maybe a Windows issue (you're testing on Linux, right)?

                        Thanks...

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mzimmers
                          wrote on 11 May 2020, 15:03 last edited by
                          #28

                          This problem has to do with setting the button's visibility. If I disable this line in my widget c'tor:

                          //    ui->pushButtonNics->setVisible(false);
                          

                          My slot receives the signal, and opens the Nics dialog. After the dialog closes, I set the button to not visible, and the problem recurs.

                          This problem exists on Windows 10, but not on MacOS. Could it be a bug?

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on 11 May 2020, 15:15 last edited by
                            #29

                            One silly test, did you try to make the button invisible after calling connect. AFAIK, it should have no relation but it's worth a shot.

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

                            M 1 Reply Last reply 11 May 2020, 15:24
                            0
                            • S SGaist
                              11 May 2020, 15:15

                              One silly test, did you try to make the button invisible after calling connect. AFAIK, it should have no relation but it's worth a shot.

                              M Offline
                              M Offline
                              mzimmers
                              wrote on 11 May 2020, 15:24 last edited by
                              #30

                              @SGaist yes, that's how I had it:

                              Widget::Widget(QWidget *parent) :
                                  QWidget(parent),
                                  ui(new Ui::Widget)
                              {
                                  ui->setupUi(this);
                              
                                  // create and connect a KeyPress object.
                                  m_keyPress = new KeyPress(this);
                                  connect(m_keyPress, &KeyPress::keyEvent, this, &Widget::handleKeyEvent);
                                  connect(ui->pushButtonNics, &QPushButton::clicked, this, &Widget::on_pushButtonNics_clicked);
                                  installEventFilter(m_keyPress);
                              
                                  // hide the button for the NICs window.
                              //    ui->pushButtonNics->setVisible(false);
                              }
                              
                              1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                mzimmers
                                wrote on 18 May 2020, 17:19 last edited by
                                #31

                                Update: I submitted a bug report on this; no movement on it yet.

                                One of my users noticed that the application is now rather CPU-intensive. I verified that it was the key filter by disabling this code in my main widget:

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

                                Here's the filter:

                                bool KeyPress::eventFilter(QObject *obj, QEvent *ev)
                                {
                                    Q_UNUSED(obj)
                                
                                    bool rc = false;
                                    int key;
                                    QKeyEvent *qke;
                                    QEvent::Type type = ev->type();
                                    if (type == QEvent::ShortcutOverride || type == QEvent::KeyRelease)
                                    {
                                        qke = static_cast<QKeyEvent *>(ev);
                                        key = qke->key();
                                
                                        // don't bother signaling when the key isn't meaningful to us.
                                        if (key == 'c' || key == 'C' || key == 'd' || key == 'D')
                                        {
                                            emit keyEvent(*ev, key);
                                        }
                                        rc = true;
                                    }
                                    else
                                    {
                                        rc = QObject::eventFilter(obj, ev);
                                    }
                                    return rc;
                                }
                                

                                I don't see anything really inefficient in my code, but with this enabled, the app uses ~15% of my CPU (on an i3) at idle. Is this to be expected, or am I doing something wrong?

                                Thanks...

                                1 Reply Last reply
                                0
                                • S Offline
                                  S Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on 18 May 2020, 17:24 last edited by
                                  #32

                                  What type of widgets are you checking ?
                                  You can add an additional check for the obj parameter class to avoid further checks.

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

                                  JonBJ M 2 Replies Last reply 18 May 2020, 17:26
                                  0
                                  • S SGaist
                                    18 May 2020, 17:24

                                    What type of widgets are you checking ?
                                    You can add an additional check for the obj parameter class to avoid further checks.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on 18 May 2020, 17:26 last edited by
                                    #33

                                    @SGaist
                                    If @mzimmers says:

                                    but with this enabled, the app uses ~15% of my CPU (on an i3) at idle

                                    assuming "idle" means not pressing any key, why is this KeyPress::eventFilter() being hit at all, let alone loads of times to use that CPU?

                                    M 1 Reply Last reply 18 May 2020, 17:51
                                    0
                                    • S SGaist
                                      18 May 2020, 17:24

                                      What type of widgets are you checking ?
                                      You can add an additional check for the obj parameter class to avoid further checks.

                                      M Offline
                                      M Offline
                                      mzimmers
                                      wrote on 18 May 2020, 17:27 last edited by
                                      #34

                                      @SGaist well, maybe that's my problem -- I'm checking the entire QWidget. (The idea was to reveal hidden buttons when certain keys were pressed.) Given that, I'm not sure there's any meaningful obj parameter checking I can do.

                                      1 Reply Last reply
                                      0
                                      • JonBJ JonB
                                        18 May 2020, 17:26

                                        @SGaist
                                        If @mzimmers says:

                                        but with this enabled, the app uses ~15% of my CPU (on an i3) at idle

                                        assuming "idle" means not pressing any key, why is this KeyPress::eventFilter() being hit at all, let alone loads of times to use that CPU?

                                        M Offline
                                        M Offline
                                        mzimmers
                                        wrote on 18 May 2020, 17:51 last edited by
                                        #35

                                        @JonB I suspect I'm doing something wrong with my use of the filter, but I'm not sure what to change. I think my filterEvent() is being called for all events, not just for key events.

                                        JonBJ 1 Reply Last reply 18 May 2020, 17:54
                                        0
                                        • M mzimmers
                                          18 May 2020, 17:51

                                          @JonB I suspect I'm doing something wrong with my use of the filter, but I'm not sure what to change. I think my filterEvent() is being called for all events, not just for key events.

                                          JonBJ Offline
                                          JonBJ Offline
                                          JonB
                                          wrote on 18 May 2020, 17:54 last edited by
                                          #36

                                          @mzimmers said in using QKeyEvents:

                                          I think my filterEvent() is being called for all events, not just for key events.

                                          I suspect that is more like it ;-) I would worry about that before anything else :)

                                          Use a debugger or qDebug()s to at least see when your filter is being hit, when the user isn't doing anything?

                                          M 1 Reply Last reply 18 May 2020, 18:34
                                          0

                                          • Login

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