Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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