[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(QEventLoop::DialogExec); 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.