Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-51856

Any QWidget with a focus proxy inside a QGraphicsProxyWidget will fire QEvent::FocusIn on every mouse click

    XMLWordPrintable

Details

    • 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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            peppe Giuseppe D'Angelo
            christophermanthei Christopher Manthei
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes