[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;
    show();
    qApp->setActiveWindow( this );
    setFocus();
    qApp->installEventFilter( this );
    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;
    removeEventFilter(this);
    qApp->removeEventFilter( this );
    hide();
    
    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 );
    #endif

    #if !defined(Q_WS_X11)
    } else if( event->type() == QEvent::ApplicationDeactivate ) {
    exitEventLoop( QChar() );
    return MyBaseClassWidget::eventFilter( obj, event );
    #endif
    }
    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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.