3
votes

After porting from Qt 4.8 to 5.4 I've got next problem... When I'm showing multiple widgets with Qt::Popup flag set, only the first of them can receive mouse enterEvent or leaveEvent.
With 4.8.0 version all of popup widgets reacted on mouse entering or leaving.

Is this normal for Qt5 or some bug?

With code below only the first popup widget w1 reporting about enterEvent and leaveEvent on mouse moving. If Qt::Popup flag is not set all widgets report.

class PopupWidget : public QWidget
{
Q_OBJECT
public:
    explicit PopupWidget( QWidget *parent = 0):QWidget(parent)
    {
    setWindowFlags( windowFlags() | Qt::Popup );
    setAutoFillBackground( true );
    setFixedSize( 100, 100 );
    }

protected:
    void    enterEvent(QEvent * event)
    { qDebug() << "enterEvent"; }

    void    leaveEvent(QEvent * event)
    { qDebug() << "leaveEvent"; }
};

void main()
{
    PopupWidget w1, w2, w3;

    w1.move( mapToGlobal(QPoint(0,0)) );
    w1.show();

    w2.move( mapToGlobal(QPoint(110,0)) );
    w2.show();

    w3.move( mapToGlobal(QPoint(220,0)) );
    w3.show();
}
1

1 Answers

1
votes

Same problem. Seems, in Qt5 you can't use multiple popups at the same time. Even standard hover effects for buttons stop working if you open popup inside popup. I started to use Qt::Tool instead of Qt::Popup to avoid this problem.

In window constructor (I use QFrame as a base class):

setWindowFlags (Qt::Tool | Qt::FramelessWindowHint);

Opening window:

QFrame::show();
QApplication::setActiveWindow (this);

Handling focus out events:

bool event (QEvent * e)
{ if(e->type() == QEvent::WindowDeactivate) hide();
  return QFrame::event (e);
}

Global event filter to catch focus out events caused by wheel (install it on your main window):

bool eventFilter (QObject * obj, QEvent * e)
{ if(e->type() == QEvent::Wheel)
  { QWidget * w = qobject_cast <QWidget*> (obj);
    QWidget * aw = QApplication::activeWindow();
    if(w && !w->isActiveWindow() && aw != m_MainWindow) aw->hide();
  }
  return QObject::eventFilter (obj, e);
}