How to prevent QWidget::show() with QWidget::showEvent()
-
Hello everybody,
I have a QMainWindow which instantiate a QWidget subclass. I want to fill my subclass with remote data, so I want to prevent the "show()" slot, ignore it and make the request, then really show the subclass widget.
I've reimplemented "showEvent(QShowEvent *)" and made it ignore the event, a qDebug show me it worked and is ignored, but still showing the widget.
What did I miss ?
Thank you for your help.Subclass:
@void Groups_Materials::showEvent(QShowEvent *event)
{
event->ignore();
qDebug() << "Event accepted: " << event->isAccepted(); // Return: false
}@How it is called:
@this->m_groupsMaterialsWidget = new Groups_Materials(this->m_parent);
this->m_groupsMaterialsWidget->setWindowModality(Qt::ApplicationModal);
this->m_groupsMaterialsWidget->setAttribute(Qt::WA_DeleteOnClose);
this->m_groupsMaterialsWidget->show();@What is written in the console when calling these methods:
@Event accepted: false@ -
[quote author="Lukas Geyer" date="1356944297"]You can't do that using QWidget::showEvent();[/quote]
Why not ?
I've also fixed my problem. Actually, I was using the "Qt::Sheet" flag and I don't know why, when I removed it, the event were ignored and the widget weren't shown. But I still want to know why I can't reimplement "QWidget::showEvent()" to do what I want? I thought it was the purpose of reimplementing it :D
Thank you anyway.
-
Because unlike closeEvent(), showEvent() (as well as hideEvent()) are "informational events only":http://code.woboq.org/qt5/qtbase/src/widgets/kernel/qwidget.cpp.html#7082. They are raised to inform you that the widget is about to be shown (resp. hidden), irregardless wheter you accept or ignore the event.
-
I understant what you say, but 2 things:
Actually, it worked when I removed the Qt::Sheet flag, the widget were correctly ignored, but I couldn't accept it at the next "show()" call (showEvent() seems to be called only once, even with 2 calls).
Even on the link you gave me, it says: "send the show event before showing the window", how do you know it's informational only :/ ?
Thank you for your help.
-
If you take a look at the code you'll see that the widget is shown (<code>show_sys()</code>), regardless whether the event is accepted or not. It might make more sense if you take a look at the code for the "close event":http://code.woboq.org/qt5/qtbase/src/widgets/kernel/qwidget.cpp.html#7438 (<code>if (... && !e.isAccepted()) { ... return false; }</code>) for comparison.
It can be quite confusing but as a rule of thumb every event is informational only, unless the documentation says otherwise.
The fact that you don't receive subsequent show events for <code>show()</code> is an indicator that your widget is already shown (and so ignoring the event did not prevent that), although beeing invisible (for whatever reason).
I'm not quite sure if there is even a non-hackish way of suppressing <code>show()</code>, overriding <code>setVisible()</code> included.
You either don't <code>show()</code> the widget in the first place unless the data is available or you simply <code>show()</code> the widget and display an loading indicator until the data is available. Is this an option for you?