Important: Please read the Qt Code of Conduct -

[Resolved] QWidget window flag behavior changed in Qt 4.8?

  • I have a certain QWidget derived class.

    Look at the window flags i'm giving it. In my app it functions like the drop down component of the combo box:

    @setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);@

    with Qt 4.7.4, the "FocusOutEvent" is called when I click outside of the widget, even if the click is on the window caption. I use the event to hide my widget. That's the desired behavior I'd like to see. With Qt 4.8 however, "FocusOutEvent" is never called when clicking outside my widget on non-focus receiving elements and/or my window caption, thus, it still sticks around. I can actually drag the window away from my still-visible popup widget...

    Something changed in Qt 4.8 something changed. Is there a way around it?

  • None of the conventional techniques work here. No mouse grabbing, no eventFilter. Qt doesn't get any event when i click my OSX window caption. I show my popup, grab my OSX window caption, and drag the window away from the still opened popup. For me, this is a new deal-breaker bug introduced in Qt 4.8. Qt 4.7.4 works well, the popup disappears as soon as I click the window caption. Reluctantly I am forced to revert to 4.7.4. Pity.

  • This really sucks as I have to revert to Qt 4.7.4, missing out on all the bug fixes of Qt 4.8

  • Have you already filed a bug report?

  • I intend to today.

  • Perfectly. Please add a link to this thread to the bug report.

  • added.

  • I have a similar use case and I install an eventFilter on the QApplication object - that receives the mouse click. I then check if the click is on my object or any subwidgets of it. If not, I close that widget. That special popup is used with exec(), just like a menu or a dialog. I'll show the implementation of exec() and the eventFilter() here:

    QChar MySpecialPopup::exec()
    if( _eventLoop ) {
    qWarning("MySpecialPopup::exec: Recursive call detected");
    return QChar();

    _selectedChar = QChar();
    bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_DeleteOnClose, false);
    _dialogIsOpen = true;
    qApp->setActiveWindow( this );
    qApp->installEventFilter( this );
    QEventLoop eventLoop;
    _eventLoop = &eventLoop;
    QPointer<MySpecialPopup> guard = this;
    connect( qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
             this, SLOT(focusChanged(QWidget*,QWidget*)));
    (void) eventLoop.exec&#40;QEventLoop::DialogExec&#41;;
    disconnect( qApp, SIGNAL(focusChanged(QWidget*,QWidget*)),
                this, SLOT(focusChanged(QWidget*,QWidget*)));
    _dialogIsOpen = false;
    qApp->removeEventFilter( this );
    if (guard.isNull())
        return QChar();
    _eventLoop = 0;
    if (deleteOnClose)
        delete this;
    return _selectedChar;


    bool MySpecialPopup::eventFilter(QObject *obj, QEvent *event)
    if( !_dialogIsOpen )
    return MyBaseClassWidget::eventFilter( obj, event );

    if(event->type() == QEvent::MouseButtonPress
       && obj != this 
       && !findChildren<QObject *>().contains( obj )
     ) {
        exitEventLoop( QChar() );
        return MyBaseClassWidget::eventFilter( obj, event );

    #if !defined(Q_WS_MAC)
    } else if( event->type() == QEvent::WindowDeactivate ) {
    exitEventLoop( QChar() );
    return MyBaseClassWidget::eventFilter( obj, event );

    #if !defined(Q_WS_X11)
    } else if( event->type() == QEvent::ApplicationDeactivate ) {
    exitEventLoop( QChar() );
    return MyBaseClassWidget::eventFilter( obj, event );
    return MyBaseClassWidget::eventFilter( obj, event );

  • Volker, you are a mad scientist ;-)
    I'll give that a try in the next couple of days.

Log in to reply