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@



  • You can't do that using QWidget::showEvent(); reimplement QWidget::setVisible() or use QEvent::Polish resp. QEvent::PolishRequested instead (which, however, does not allow you the suppress the showing as well).



  • [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?


Log in to reply
 

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