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.8k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mzimmersM 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