Denis Turgenev
Denis Turgenev

Reputation: 138

How to get resizeEvent-already-executed?

I have a QDialog-inherited class and one of its sub-window is initialized on resizeEvent like this.

void OpenGLWindow::resizeEvent(QResizeEvent *event) {

    QWindow::resizeEvent(event);

    // initialize on  first call
    if (m_context == nullptr)
        initOpenGL();

    resizeGL(width(), height());
}

Because OpenGL init needs width and height information, and need to adapt window size change, this init code can't move other place.

I should open this dialog and initialize some OpenGL draw objects.

m_Dialog->show();
m_Dialog->init(init_paramter); //I have to create opengl buffers of draw objects here

But unfortunately, resizeEvent() is called after init method was invoked.

e.g. current execution order is as following.

my_dialog_open_function() {
      m_Dialog->show();
      m_Dialog->init(init_paramter);
}
void OpenGLWindow::resizeEvent(QResizeEvent * event)

As OpenGL system was not initialized by resizeEvent Handler, my m_Dialog->init invoke crashes.

How can I get this execution flow?

m_Dialog->show();
void OpenGLWindow::resizeEvent(QResizeEvent * event)
m_Dialog->init(init_paramter);

Where is the proper place I can invoke my init function safely?

Upvotes: 0

Views: 257

Answers (1)

king_nak
king_nak

Reputation: 11513

As @pptaszni mentioned in his comment, initOpenGL() doesn't look like it needs size information. So first I would reconsider the design.

As for the question:
The resize event is scheduled after the show and delivered when GUI events are processed. That's after your function returns.

You can simply delay the call by posting some event, which then will be delivered after the resize event. The easiest way is to use a single shot timer:

m_Dialog->show();

// Call me in 1ms
QTimer::singleShot(1, [=]() {
   m_Dialog->init(init_paramter);
});

Note the delay of 1ms. If you call it with 0, Qt will optimize and call the handler immediately, so no gain there.

Upvotes: 1

Related Questions