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.7k 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
    #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 Offline
      mzimmersM Offline
      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 Offline
        mzimmersM Offline
        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 Offline
          mzimmersM Offline
          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 Offline
              mzimmersM Offline
              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 Offline
                  mzimmersM Offline
                  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
                    • SGaistS SGaist

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

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

                                          • Login

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