【问题标题】:How to get resizeEvent-already-executed?如何让 resizeEvent-已经执行?
【发布时间】:2021-06-21 11:38:42
【问题描述】:

我有一个 QDialog 继承的类,并且 它的一个子窗口在 resizeEvent 上初始化,就像这样。

void OpenGLWindow::resizeEvent(QResizeEvent *event) {

    QWindow::resizeEvent(event);

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

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

因为OpenGL init需要宽高信息,并且需要适应窗口大小的变化,所以这个init代码不能移动到其他地方。

我应该打开这个对话框并初始化一些 OpenGL 绘图对象。

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

但不幸的是,resizeEvent() 是在调用 init 方法之后调用的

例如当前执行顺序如下。

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

由于 resizeEvent Handler 未初始化 OpenGL 系统,我的 m_Dialog->init 调用崩溃

我怎样才能得到这个执行流程?

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

我可以在哪里安全地调用我的 init 函数?

【问题讨论】:

  • 从代码看来initOpenGL();(我假设它为m_context 分配了一些东西)不需要宽度和高度。只打电话给resizeGL(width(), height());。除非 init 方法更复杂,并且它对窗口几何有一定的依赖性。
  • 啊,谢谢。我会尝试将 (if (m_context == nullptr) initOpenGL();) 移动到全局初始化区域。
  • @pptaszni,我把initOpenGL放在构造函数里,直接崩溃了。似乎应该在创建小部件的任何回调(如 resizeEvent)中调用 initOpenGL。

标签: c++ qt qdialog


【解决方案1】:

正如@pptaszni 在他的评论中提到的,initOpenGL() 看起来不需要大小信息。所以首先我会重新考虑设计。

至于问题:
调整大小事件安排在演出之后,并在处理 GUI 事件时交付。那是在你的函数返回之后。

您可以通过发布一些事件来简单地延迟调用,然后在调整大小事件之后传递。最简单的方法是使用单次计时器:

m_Dialog->show();

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

注意1ms的延迟。如果你用 0 调用它,Qt 会优化并立即调用处理程序,所以没有任何收获。

【讨论】:

  • 感谢 king_nak,使用您的计时器,我可以 100% 获得流量(显示、调整大小事件、初始化)吗?还是 99% 的工作和 1%(显示、初始化、resizeEvent)?如果不是 100%,可能会导致隐藏错误。但是如果你在实际项目中有这种方式的真实经验,我会在我的项目中使用它。
  • 我尝试了 1ms、100ms,当我给 1ms 时,我得到了(显示、初始化、崩溃)。当我给 100 毫秒时,我得到 (show, resizeEvent, init)。所以你认为如果我给了足够的时间,那么我可以得到 100% 的成功吗?可惜不能给你看视频截图
  • 为了确保您需要像that 那样做某事,并在满足条件(resizeEvent)后致电您的init。但这是您问题的直接解决方案,看起来并不是您问题的最佳解决方案。我宁愿调查这个 openGL 窗口设置的确切前提条件是什么,不幸的是我不是专家。
  • 我确实在实际项目中使用了这种设置(也就是说,在处理了先前调用的事件之后推迟调用)。但是,永远不要在show 之后直接使用调整大小事件...似乎调整大小不是由我假设的节目直接触发的,所以它可能不是最佳解决方案:/ 一种方法是增加超时(脏),或使用像@pptaszniSuggestet(脏-ish)这样的条件变量。最好不要依赖于 GL 的一次性初始化的调整大小。这提醒了我:你能在表演活动中做到吗?
  • 有 100 毫秒,我很高兴。谢谢你。到目前为止,我没有遇到任何崩溃。
猜你喜欢
  • 2016-07-21
  • 2018-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
相关资源
最近更新 更多