7

I have an app (not related to any game where the W/A/S/D keys may have special meanings for navigation) where there is a QFrame. I overrode the keyPressEvent() to get the text being typed through keyboard while focus in on that QFrame. This is my code:

void MyFrame::keyPressEvent(QKeyEvent *event)
{
    qDebug() << "At least came here" << endl;
    QString text = event->text();
    qDebug() << "Text: " << text << endl;
}

When I type characters from keyboard one at a time, for all characters and numbers, both statements are logged correctly. But for these four keys neither of the log statements are executed, i.e the event handler is not even firing. What is wrong?

Edit: After going though the examples, I tried to form a minimal working example of my bug. This is what I have got. Same problem here as well with doing it through event filter. Only for those four characters it is not logged.

bool MyWidget::eventFilter(QObject *obj, QEvent *event)
{

    if (event->type() == QEvent::KeyPress)
    {
        //this never gets printed
        qDebug() << "Phew!" << endl;
        return true;

    }
    if (qobject_cast<ChildWidget *>(obj) != nullptr)
    {


        ChildWidget *option = qobject_cast<ChildWidget *>(obj);
        if (event->type() == QEvent::Enter || event->type() == QEvent::MouseMove)
        {
            //do stuff
            return true;
        }
        if (event->type() == QEvent::Leave)
        {
            //do stuff
            return true;
        }
        return QWidget::eventFilter(obj, event);
    }
    else
    {
        // pass the event on to the parent class
        return QWidget::eventFilter(obj, event);
    }
}

MyWidget::MyWidget()
{
   //do other initialization
   this->installEventFilter(this);
}

void MyWidget::keyPressEvent(QKeyEvent *event)
{
    qDebug("At least came here");
    QString text = event->text();
    //this prints out whenever I type any character, excpet W/A/S/D
    qDebug() << text;
}
SexyBeast
  • 7,913
  • 28
  • 108
  • 196

4 Answers4

5

QFrame class is designed as a simple frame object. It does not works with any input by default. So you must specifify explicitly a focus policy which allows to retrieve keyboard input events using QWidget::setFocusPolicy() method. QFrame by default has Qt::NoFocus policy. Try to set frame's focus policy property to Qt::StrongFocus and launch your program again.

Pie_Jesu
  • 1,894
  • 3
  • 16
  • 30
  • It is working for all keys except those four, so I guess focus policy is not the problem. But I have checked, nowhere we are disabling anything so as not accept those four keys.. – SexyBeast Jul 27 '15 at 09:47
  • In my answer I used a `QFrame`, I didn't set its `focus policy` and the keyboard input events are received. – Tarod Aug 02 '15 at 11:35
  • @Tarod that's because of event filter. It receives event anyways. And my answer complements questions example where `keyPressEvent` is overrided. – Pie_Jesu Aug 04 '15 at 11:39
3

Not sure if I'm misunderstanding something, but the following code is working well and I see all the keys in the log (even capitalized) except key "w".

Here you have:

Edit#1: installed an event filter on the QApplication to get the objects which are filtering the events.

myframe.pro

TEMPLATE = app

QT     += widgets
SOURCES += main.cpp \
           myframe.cpp 

HEADERS += myframe.h 

main.cpp

#include <QtWidgets/QApplication>
#include <QDebug>

#include "myframe.h"

class QApplicationFilter: public QObject
{
    public:
        QApplicationFilter(): QObject() {};
        ~QApplicationFilter() {};

        bool eventFilter(QObject* obj, QEvent* event)
        {
            qDebug() << "QApplicationFilter: "
                     << obj->objectName()
                     << " - event type: "
                     << event->type();
            return QObject::eventFilter(obj, event);            
        };  
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);    
    a.installEventFilter(new QApplicationFilter());

    MyFrame mf;
    mf.show();
    return a.exec();
}

myframe.h

#ifndef MYFRAME_H
#define MYFRAME_H

#include <QtWidgets/QFrame>

class MyFrame : public QFrame
{
    Q_OBJECT

public:
    MyFrame();
    bool eventFilter(QObject *object, QEvent *event);

protected:
    void keyPressEvent(QKeyEvent *event);
};

#endif

myframe.cpp

#include <QDebug>
#include <QKeyEvent>
#include "myframe.h"

MyFrame::MyFrame()
{
   this->installEventFilter(this);
}

bool MyFrame::eventFilter(QObject *object, QEvent *event)
{
    if (object == this && event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        if (keyEvent->key() == Qt::Key_W) {
            return true;
        } else {
            return false;
        }
    }
    return false;
}

void MyFrame::keyPressEvent(QKeyEvent *event)
{
    qDebug("At least came here");
    QString text = event->text();
    qDebug() << text;
}
Tarod
  • 6,732
  • 5
  • 44
  • 50
  • Yup, it works everywhere, but not in my app. I checked thoroughly (although it appears not thoroughly enough), nowhere are we disabling any input with those 4 characters. – SexyBeast Jul 27 '15 at 09:48
  • The only way I know to intercept events is using `bool QObject::eventFilter(QObject * watched, QEvent * event)`. I've updated the code so now the application doesn't process the "w" key. Do you have an event filter installed in your application? – Tarod Jul 27 '15 at 11:06
  • @Cupidvogel Thank you. Well, I copy&pasted your code, changing `ChildWidget` by `MyFrame` in order to compile properly, and I see "Phew!" for all keys I press. BTW, you should return `false` if you want to get that key in your `keyPressEvent` method. Could please show us your header file? Or at least, the header file for that example code that is not working. – Tarod Jul 28 '15 at 06:00
  • It is still not working. I guess the problem lies in our codebase (which is huge and I cannot possibly reproduce a minified version of it!), and somewhere we are handling those four keys.. – SexyBeast Jul 28 '15 at 10:23
  • @Cupidvogel Maybe installing an event filter on the QApplication could help you to find the object which is "eating" those events. Please, see the new edit. – Tarod Jul 28 '15 at 11:18
  • Okay. Trying this. Give me some time.. :) – SexyBeast Jul 28 '15 at 11:57
  • Hi, I verified, the problem is not restricted to my custom widget, when I am using a normal Qt combo-box with various options, the keypress events on those four keys don't do anything, while for other keys, it does the usual thing, shift the focus to the first option starting with that letter. – SexyBeast Jul 30 '15 at 17:16
  • @Cupidvogel I think it's the same problem. Did you install the event filter I mentioned two days ago? Are you working on Linux? You could search the line of code `eventFilter` or `installEventFilter` using `grep` in order to find if there are any filter. – Tarod Jul 31 '15 at 06:59
  • Yes, I did grep. I have been using it in 2 or 3 other places for other widgets, but they are all for capturing `hover` events, and working fine. This is the first place where I tried it with a `keypress` event. – SexyBeast Jul 31 '15 at 07:21
  • @Cupidvogel OK. But if you install the event filter on the QApplication, do you receive all the events - even WASD keys? I have been reading on the Internet, but the only way I know to disable key events is using event filters. At least with Qt. Because I'm assuming the problem is related to Qt and not with code in C++ or other piece of non-Qt-code in your application. – Tarod Jul 31 '15 at 09:04
2

I find the fact the keys W, A, S, and D are typical game movement keys and also the keys you are having issues with to be a very suspicious coincidence. My best guess is you have some kind of "gaming" keyboard, system extension or custom driver. I'm thinking of things like a "virtual joystick", "power keys", VR software, macro software, etc. I'd be more confident in that answer if it wasn't happening on both a Mac and a PC (unless you use the same keyboard or other hardware). Either way I'd try another keyboard and start the system in safe mode with other programs closed just to make sure these key events aren't being intercepted/modified at the system level.

SpliFF
  • 38,186
  • 16
  • 91
  • 120
  • Yep, I suspected the same when I found out only those four keys are not working. However I have tried in a number of systems - both Windows and Mac, all with same problem.. :( – SexyBeast Aug 01 '15 at 12:40
  • Were they all your systems? Maybe you are installing a common program/driver on all of them? – SpliFF Aug 01 '15 at 12:45
  • No, I tried in my Mac and some other Mac. Then I tried in 2 or 3 Windows laptops. Same problem everywhere.. :( – SexyBeast Aug 01 '15 at 13:00
1

As first please do what Meefte said (Provide a Minimal, Complete, and Verifiable example"). And take a look at your other programms running. Did you allready check that something blocks it? Try your code on another computer or deactivate any tool you installed for your keyboard. I guess something else blocks your input. Best regards

Frederik Ubben
  • 143
  • 1
  • 12