Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. using QKeyEvents
Qt 6.11 is out! See what's new in the release blog

using QKeyEvents

Scheduled Pinned Locked Moved Solved General and Desktop
40 Posts 4 Posters 12.5k 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on 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
    • mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on 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
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on 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

        mzimmersM 1 Reply Last reply
        0
        • SGaistS SGaist

          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.

          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on 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
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on 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
            • mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on 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
              • mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on 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
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 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

                  mzimmersM 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    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.

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on 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
                    • mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on 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
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 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 mzimmersM 2 Replies Last reply
                        0
                        • SGaistS SGaist

                          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 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?

                          mzimmersM 1 Reply Last reply
                          0
                          • SGaistS SGaist

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

                            mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on 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

                              @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?

                              mzimmersM Offline
                              mzimmersM Offline
                              mzimmers
                              wrote on 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
                              0
                              • mzimmersM mzimmers

                                @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 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?

                                mzimmersM 1 Reply Last reply
                                0
                                • JonBJ JonB

                                  @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?

                                  mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #37

                                  @JonB

                                      qDebug() << QTime::currentTime().toString();
                                  

                                  Got about 6000 hits in ~2 seconds of run time. That explains the CPU usage.

                                  I have no idea what could possibly be generating that many events, though.

                                  JonBJ 1 Reply Last reply
                                  0
                                  • mzimmersM mzimmers

                                    @JonB

                                        qDebug() << QTime::currentTime().toString();
                                    

                                    Got about 6000 hits in ~2 seconds of run time. That explains the CPU usage.

                                    I have no idea what could possibly be generating that many events, though.

                                    JonBJ Offline
                                    JonBJ Offline
                                    JonB
                                    wrote on last edited by
                                    #38

                                    @mzimmers
                                    Start by debugging out ev->type()!

                                    mzimmersM 1 Reply Last reply
                                    0
                                    • JonBJ JonB

                                      @mzimmers
                                      Start by debugging out ev->type()!

                                      mzimmersM Offline
                                      mzimmersM Offline
                                      mzimmers
                                      wrote on last edited by mzimmers
                                      #39

                                      @JonB the great majority were:

                                      QEvent::UpdateRequest
                                      QEvent::Paint

                                      UPDATE: I managed to eliminate the flood of events, but...that didn't have an effect on my CPU usage. The problem is definitely in the KeyEvent class -- when I comment it out, CPU usage is nil. Anyone have any ideas?

                                      1 Reply Last reply
                                      0
                                      • mzimmersM Offline
                                        mzimmersM Offline
                                        mzimmers
                                        wrote on last edited by
                                        #40

                                        Update on this, documented here

                                        The behaviour is different because clicked is emitted on button down on macOS, but on button up on the other two[Windows and Linux]. While the keyboard keys are down, the QPushButton stays down. That's a UX difference caused by how the OS itself behaves.

                                        So, my idea for using the keys goes out the window...I'll think of something else.

                                        The performance issue is a mystery, but I'm going to open a new thread on that. Thanks to everyone for looking.

                                        1 Reply Last reply
                                        1

                                        • Login

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