我正在使用QOpenGLWidget,无法理解应将绘图代码放在哪里:重写paintGL内或重写paintEvent内。
我应该调用这些函数的基类版本吗?
这些功能如何连接? paintGL启动paintEvent还是反之?也许是由于非相交的原因(例如,还原窗口,绘制一些3D几何形状,更改窗口大小)而启动的吗?这些原因是什么?
最后,当我更改几何图形时如何强制重新渲染图形?我应该叫什么方法?
最佳答案
简短的答案:在QOpenGLWidget
中打开GL绘图应该在QOpenGLWidget::paintGL()
中进行。
当调用OpenGL命令时,先决条件是响应。 OpenGL上下文已被激活。这是 QOpenGLWidget::paintGL()
确保的:
顺便说一句。另一个前提条件是响应。 OpenGL上下文已全部创建。
为了了解更多信息,我在 QOpenGLWidget::paintEvent()
(在woboq.org上)进行了更深入的研究:
void QOpenGLWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
Q_D(QOpenGLWidget);
if (!d->initialized)
return;
if (updatesEnabled())
d->render();
}
QOpenGLWidget::initializeGL()
的调用。)通过眼睛跟踪代码(严格来说:单击鼠标),
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
的描述中得到了回答:以防万一,我误解了OP的意图,而实际的问题是将
QPainter
绘图放置在QOpenGLWidget
中的位置–我曾经为SO: Paint a rect on qglwidget at specifit times编写了关于将OpenGL命令和QPainter
绘图混合在paintGL()
中的答案。关于c++ - 何时在Qt中使用paintEvent和paintGL?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50855257/