PDA

View Full Version : QEvent::KeyPress problem, when will this event appear?



batileon
16th June 2011, 08:56
I have a widget and installed event filter to it,


bool MyClass::eventFilter( QObject*, QEvent *event )
{
qDebug("EventFilter type: %d", event->type());
QKeyEvent *ke = (QKeyEvent *) event;
int keyValue = ke->key();
if(event->type() == QEvent::KeyPress )
{
switch ( keyValue )
{
case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: case Qt::Key_3 : case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9 :
ListBoxA->numClicked((char *)ke->text().latin1());
break;
}
return true;
}
return false;
}



From the qDebug(), I found that the QEvent::KeyPress appear only once, that is, the first time I press a keyboard input. And all keyboard input afterward seems disappeared, no more can be received. However if I change it to QEvent::KeyRelease, I found that it works!

Can anyone tell me why is this happening? When will the KeyPress event occur? is it the eventFilter is not working or something else blocked the event?

QT4.6.3 used.

Thanks!

Santosh Reddy
16th June 2011, 09:23
Not sure about your problem but, you should cast the event only after confirming that it is KeyEvent, like this

moreover it is safer to use c++ style casting

call the objects event processing if not consuming the event


if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
qDebug("Ate key press %d", keyEvent->key());
return true;
} else {
// standard event processing
return QObject::eventFilter(obj, event);
}

batileon
16th June 2011, 09:32
Oops, my typo, the casting IS in the if loop actually.


bool MyClass::eventFilter( QObject*, QEvent *event )
{
qDebug("EventFilter type: %d", event->type());
if(event->type() == QEvent::KeyPress )
{
QKeyEvent *ke = (QKeyEvent *) event;
int keyValue = ke->key();

switch ( keyValue )
{
case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: case Qt::Key_3 : case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9 :
ListBoxA->numClicked((char *)ke->text().latin1());
break;
}
return true;
}
return false;
}


I want to know when QEvent::KeyPress will appear?
From my program, the following events had been captured:
QEvent::KeyPress (type no. = 6) [***can be captured only for the first time***]
QEvent::KeyRelease (type no. = 7)
QEvent::ShortcutOverride (type no. = 51)
QEvent::UpdateRequest (type no. = 77)

Why is there no more keyPress event after my first keyboard press?

Santosh Reddy
16th June 2011, 09:47
Did you try adding "return QObject::eventFilter(obj, event);"?

Did you install in on ListBoxA?

batileon
16th June 2011, 12:26
I don't understand, do u mean calling it recursively?

I did install it to the widget I need.

stampede
16th June 2011, 12:36
It's not recursive, it's just base-class implementation, you should call it like Santosh suggested.

batileon
16th June 2011, 12:38
I did try, but still there's no more KeyPress event after the first hit.

Rachol
16th June 2011, 12:50
Does your code look like this?:



bool MyClass::eventFilter( QObject* obj, QEvent *event )
{
qDebug("EventFilter type: %d", event->type());
if(event->type() == QEvent::KeyPress )
{
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
int keyValue = ke->key();

switch ( keyValue )
{
case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: case Qt::Key_3 : case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9 :
ListBoxA->numClicked((char *)ke->text().latin1());
break;
}
return true;
}
return QObject::eventFilter(obj,event);
}

Please notice that in following line, QObject can be something else, for example QWidget if that is the base class of MyClass:


return QObject::eventFilter(obj,event);

Santosh Reddy
16th June 2011, 14:19
I don't understand, do u mean calling it recursively?
It will not cause recursion, should you have figured it out by now....


I did install it to the widget I need.
Please understand my question, did you install the filter on ListBoxA? Yes / No?
You are modifying ListBoxA in the filter code, are you sure this is not causing the problem?

stampede
16th June 2011, 15:20
I don't believe that key press events are not generated, maybe your widget loses focus and the events are sent to other widgets ? Install this test event filter on QApplication object and check for KeyPress events:


bool MyClass::eventFilter( QObject* obj, QEvent *event )
{
if(event->type() == QEvent::KeyPress )
{
qDebug() << "got keyPress on object" << obj;
}
return QObject::eventFilter(obj,event);
}

// and somewhere
MyClass * myObj = ...
...
qApp->installEventFilter( myObj );


----
edit:
one more question, maybe reimplementing keyPressEvent for ListBox could be better for your task ? I mean, for me it sounds more sensible to handle specific key press behaviour in class method, rather than in event filter. Or is there another reason why you want to do that this way (event filtering vs. reimplementing keyPressEvent) ?

batileon
17th June 2011, 06:02
Thanks all for your help. I have found the problem and solution.

ListBoxA actually contains a Q3ListBox list and some other QButtons
In ListBoxA::numClicked(char* text), it will insert a new item to the Q3ListBox 'list' :

list->insertItem( inputText );

and seems the newly added item has no event filter attachment
it works fine after I install the event filter to 'list' instead of ListBoxA.

However, I am still wondering why KeyRelease event can still be fetched in my previous cases. What's the differences between QEvent::KeyPress and QEvent::KeyRelease ???

Santosh Reddy
17th June 2011, 06:23
it works fine after I install the event filter to 'list' instead of ListBoxA.
This is what I suspected, you were installing filer on ListBoxA, and modifying the ListBoxA inside the event filter code. I tried to ask you couple of times.

Did you install in on ListBoxA?

Please understand my question, did you install the filter on ListBoxA? Yes / No?
You are modifying ListBoxA in the filter code, are you sure this is not causing the problem?
It's nice that you have found the problem.