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 5.6k 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 Extensions
                                        • Unsolved