何时在Qt中使用paintEvent和paintGL? [英] When to use paintEvent and paintGL in Qt?

查看:185
本文介绍了何时在Qt中使用paintEvent和paintGL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using QOpenGLWidget and can't understand where should I put drawing code: inside overriden paintGL or inside overriden paintEvent.

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

Should I call base class versions of these functions?

这些功能如何连接?paintGL启动paintEvent还是反之?也许是由于非相交原因(例如,还原窗口,绘制某些3D几何形状,更改窗口大小)而启动的吗?那么这些原因是什么?

How these functions are connected? paintGL launches paintEvent or vice-versa? Maybe they launch as a result of non intersecting reasons (i.e. restore window, draw some 3D geometry, change window size)? What are these reasons then?

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

Finally, how to force rerender of graphics when I change geometry? What method should I call?

推荐答案

简而言之:在 QOpenGLWidget 中打开GL绘图应该在 QOpenGLWidget :: paintGL()中进行.

The short answer: Open GL drawing in QOpenGLWidget should happen in QOpenGLWidget::paintGL().

当应调用OpenGL命令时,先决条件是响应.OpenGL上下文已被激活.这就是 QOpenGLWidget :: paintGL() 确保:

When OpenGL commands shall be called, a pre-condition is that the resp. OpenGL context has been activated before. This is what QOpenGLWidget::paintGL() ensures:

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

There is no need to call makeCurrent() because this has already been done when this function is called.

在调用此函数之前,上下文和帧缓冲区已绑定,并且通过调用glViewport()设置了视口.

Before invoking this function, the context and the framebuffer are bound, and the viewport is set up by a call to glViewport().

顺便说一句.另一个前提条件是响应.OpenGL上下文已全部创建.

Btw. another pre-condition is that the resp. OpenGL context has been created at all.

要了解更多有关此内容的信息,我进行了更深的研究–在 QOpenGLWidget :: paintEvent()中 (在woboq.org上):

To find out more about this I digged a bit deeper – in QOpenGLWidget::paintEvent() (on 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()的调用.)

paint事件请求渲染.

The paint event requests rendering.

通过眼睛跟踪代码(严格来说:单击鼠标), d-&r; render()调用 QOpenGLWidgetPrivate :: render(),该代码最终又调用 QOpenGLWidgetPrivate :: invokeUserPaint(),这里是:

Following the code by eyes (stricly speaking: mouse clicks), d->render() calls QOpenGLWidgetPrivate::render() which in turn calls finally QOpenGLWidgetPrivate::invokeUserPaint() and here we are:

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渲染肯定会中断.​​)

So, if QOpenGLWidget::paintEvent() is overloaded then it should call the paintEvent() of base class. (Otherwise, the OpenGL rendering will certainly break.)

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

Finally, how to force rerender of graphics when I change geometry? What method should I call?

这实际上是在 QOpenGLWidget 上的描述中回答的:

This is actually answered in the description on QOpenGLWidget:

如果需要从paintGL()以外的地方触发重绘(典型示例是使用计时器为场景设置动画),则应调用小部件的

If you need to trigger a repaint from places other than paintGL() (a typical example is when using timers to animate scenes), you should call the widget's update() function to schedule an update.


以防万一,我误解了OP的意图,而实际的问题是将 QPainter 绘图放在 QOpenGLWidget 中的位置?我曾经为写了一个答案:SO:在特定的时间在qglwidget上绘制rect 有关混合OpenGL命令和 QPainter paintGL()中进行绘制.


In case, I misunderstood the intention of OP, and the actual question was where to put QPainter drawing in QOpenGLWidget – I once wrote an answer to SO: Paint a rect on qglwidget at specifit times regarding mixing OpenGL commands and QPainter drawing in paintGL().

这篇关于何时在Qt中使用paintEvent和paintGL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆