[Solved]Priority of QKeySequence over keyPressEvent
-
I know how to install events. Other keystroke do work. The problem occurs with the "Return" key that is somehow eaten by the global shortcut. With your suggestion, you think I can keep my global shorcut and still receive "enter" event on my custom widget? I will try but I don't think so.
Will end up with the same problem than when reimplementing keyPressEvent, won't I? -
Still struggling with that question.
-
i think you need to listen to the QEvent::ShortcutOverride event (which is a QKeyEvent) and trigger your action manually.
Did you additionally set a shortcut context of the shortcut set on your action? -
Thanks a lot for your answer.
I played with shortcut context on my QAction, but it only work as intended with the default value.
I will have a look at your suggestion.
So you are telling me that my widget (in this case the QLineEdit) will receive a ShortcutOverride event when the Return key is pressed?
Or that I should remove my "global" shortcut and listen to ShortcutOverride on the mainwindow instead? -
You will only receive a ShortcutOverride event when there is a shortcut disambiguation.
If no disambiguation is detected a normal shortcut event is sent and the action is triggered normally (as one would expected).
Note: ShortcutOverride events aren't handled in Qt by default.I'm not 100% sure if your line edit will receive the shortcut override event, but i think so. At least it would make sense IMHO.
But to make sure you can install an event filter on the QApplication and check which widget receives the shortcut override event initially. -
Cool, that did the trick when I installed it on my QLineEdit.
Would be could if I could install it once on the QMainWindow and check if the receiver is a QSpinBox, QComboBox or QLineEdit.
However when I try that, the object returned in
@eventFilter(QObject *obj, QEvent *event)@ is always a QMainWindow -
did you install the main window on the widgets you want to inspect as an event filter?
Alternatively as i said you can install the main window on the QApplication object and check there if the watched is one of your widgets.
@qApp->installEventFilter(mainWin);@ -
Ok in the mean time I tried to install in on the qApp instead of the QMainWindow.
I now enter the eventFilter for all successive widgets that sees the keypressEvent propagation.
How do I stop this propagation? Returning true does not stop it.
@bool ApplicationMonitor::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride )
{
QKeyEvent *ev = static_cast<QKeyEvent *>(event);
if( ev->key()==Qt::Key_Return || ev->key()==Qt::Key_Enter )
{
qTrace(obj->metaObject()->className());
return true;
}
}
// standard event processing
return QObject::eventFilter(obj, event);
};@
[quote]TRACE 19/04/13 12:07:33 - QDoubleSpinBox
TRACE 19/04/13 12:07:35 - QWidget
TRACE 19/04/13 12:07:35 - QDockWidget
TRACE 19/04/13 12:07:35 - MainWindows[/quote] -
@event->accept() //stops event propagation@
But in your code you don't check the watched object against your widget objects.
-
Thanks again, your help is greatly appreciated! I'm not sure why the doc for eventFilter() says
[quote]In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.[/quote]
Should I do both: accept it and return true?If the object is not a QLineEdit, should I return false and reject the event? Or just return false?
Last question: In order to filter on receiver what is best in terms of perfomances.
@obj->metaObject()->className()=="QLineEdit"
QLineEdit* le = dynamic_cast<QLineEdit*>(obj)@ -
[quote author="Julien M" date="1366366563"]
If the object is not a QLineEdit, should I return false and reject the event? Or just return false?
[/quote]
Best would be todo nothing of both :)
You just want to inspect and trigger your action in case and don't want to manipulate the event chain at all.[quote author="Julien M" date="1366366563"]
Last question: In order to filter on receiver what is best in terms of perfomances.
@obj->metaObject()->className()=="QLineEdit"
QLineEdit* le = dynamic_cast<QLineEdit*>(obj)@[/quote]
Best would be to hold pointers to your widgets and jsut do a pointer comparison. Thats the fastest way. Don't use dynamic_cast, only if you really have to, since the it has a large performance impact. -
[quote author="raven-worx" date="1366366885"]Best would be todo nothing of both :)
You just want to inspect and trigger your action in case and don't want to manipulate the event chain at all.[/quote]No, in fact what I'm trying to do now is:- Keep my "Return" QShortcut on a QAction
- Prevent some specific widget types (eg. QLineEdit) to trigger this QAction when the user press Return in them
So my eventFilter won't trigger the action but "forbid triggering in some case" instead.
-
ah yes...sorry.
Nevertheless did you try already try to accept the event and if necessary also return true in the event filter? -
Finally did that: @event->accept(); // Prevent event propagation to parents
return false; // Allow obj to handle the "Enter" event@Thanks a lot for your help raven-worx!