Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.5.1
-
None
-
Windows
-
78edc18057d04a8329060b52d78833711bcadf39 (qt/qtbase/5.14)
Description
Embedding e.g. a QDoubleSpinBox that contains a QLineEdit that acts as a focus proxy inside a QGraphicsProxyWidget will cause every mouse click on the line edit to emit a focus in event without ever actually loosing focus.
#include <QtGui> class test : public QDoubleSpinBox { bool event( QEvent * event ) { switch (event->type()) { case QEvent::FocusIn: { setValue( value() + 1 ); } break; case QEvent::FocusOut: { setValue( value() - 1 ); } break; } return QDoubleSpinBox::event( event ); } }; int main(int argc, char **argv) { QApplication app( argc, argv ); test edit; QGraphicsScene *dummyScene = new QGraphicsScene(); dummyScene->addWidget( &edit ); QGraphicsView *view = new QGraphicsView( dummyScene ); view->show(); return qApp->exec(); }
In the code above gaining focus should set the value to one and loosing it to 0, however clicking into the line edit will increase the value on every click.
The bug is inside qwidget.cpp:
void QWidget::setFocus(Qt::FocusReason reason) { if (!isEnabled()) return; QWidget *f = this; while (f->d_func()->extra && f->d_func()->extra->focus_proxy) f = f->d_func()->extra->focus_proxy; if (QApplication::focusWidget() == f #if defined(Q_DEAD_CODE_FROM_QT4_WIN) && GetFocus() == f->internalWinId() #endif ) return; #ifndef QT_NO_GRAPHICSVIEW QWidget *previousProxyFocus = 0; if (QWExtra *topData = window()->d_func()->extra) { if (topData->proxyWidget && topData->proxyWidget->hasFocus()) { previousProxyFocus = topData->proxyWidget->widget()->focusWidget(); if (previousProxyFocus && previousProxyFocus->focusProxy()) previousProxyFocus = previousProxyFocus->focusProxy(); if (previousProxyFocus == this && !topData->proxyWidget->d_func()->proxyIsGivingFocus) return; } } #endif ...
In here the code compares the previousProxyFocus to 'this' while it instead should compare to 'f', the actual focus proxy.