什么时候在Qt中使用paintEvent和paintGL?

时间:2018-06-14 10:25:39

标签: c++ qt

我正在使用QOpenGLWidget并且无法理解我应该在哪里放置绘图代码:内部覆盖paintGL或内部覆盖paintEvent

我应该调用这些函数的基类版本吗?

这些功能是如何连接的? paintGL启动paintEvent,反之亦然?也许它们是由于非交叉原因(即恢复窗口,绘制一些3D几何图形,更改窗口大小)而启动的?那么这些原因是什么?

最后,当我更改几何体时,如何强制重新渲染图形?我应该用什么方法打电话?

1 个答案:

答案 0 :(得分:3)

简短的回答:在QOpenGLWidget中打开GL图纸QOpenGLWidget::paintGL()

当调用OpenGL命令时,前提条件是resp。之前已激活OpenGL上下文。这是QOpenGLWidget::paintGL()确保的结果:

  

无需调用makeCurrent(),因为调用此函数时已经完成此操作。

     

在调用此函数之前,绑定了context和framebuffer,并通过调用glViewport()来设置视口。

顺便说一下。另一个先决条件是OpenGL上下文已经创建了。

要了解更多相关内容,我在QOpenGLWidget::paintEvent()(在woboq.org上)深入挖掘了一下:

void QOpenGLWidget::paintEvent(QPaintEvent *e)
{
    Q_UNUSED(e);
    Q_D(QOpenGLWidget);
    if (!d->initialized)
        return;
    if (updatesEnabled())
        d->render();
}
  1. 只要尚未进行初始化,paint事件就不会执行任何操作。 (我没有深入挖掘,但我确信初始化涉及调用QOpenGLWidget::initializeGL()。)

  2. paint事件请求呈现。

  3. 按照眼睛的代码(严格地说:鼠标点击),d->render()调用QOpenGLWidgetPrivate::render(),然后调用QOpenGLWidgetPrivate::invokeUserPaint(),我们在这里:

    void QOpenGLWidgetPrivate::invokeUserPaint()
    {
        Q_Q(QOpenGLWidget);
        QOpenGLContext *ctx = QOpenGLContext::currentContext();
        Q_ASSERT(ctx && fbo);
        QOpenGLFunctions *f = ctx->functions();
        QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbo->handle();
        f->glViewport(0, 0, q->width() * q->devicePixelRatioF(), q->height() * q->devicePixelRatioF());
        inPaintGL = true;
     // vvvvvvvvvvvv
        q->paintGL();
     // ^^^^^^^^^^^^
        inPaintGL = false;
        flushPending = true;
        QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = 0;
    }
    

    (评论是我的。)

    因此,如果QOpenGLWidget::paintEvent()被重载,那么它应该调用基类的paintEvent()。 (否则,OpenGL渲染肯定会破坏。)

      

    最后,当我更改几何体时,如何强制重新渲染图形?我应该用什么方法打电话?

    实际上在QOpenGLWidget

    的说明中已经回答了这个问题
      

    如果你需要从paintGL()以外的地方触发重绘(一个典型的例子是使用计时器为场景设置动画),你应该调用widget的update()函数来安排更新。

    如果我误解了OP的意图,实际问题是QPainter绘制QOpenGLWidget的位置 - 我曾经写过SO: Paint a rect on qglwidget at specifit times关于混合OpenGL命令和QPainter中的paintGL()