【问题标题】:How to force Qt repaint QOpenglWidget in paintGL() immediately?如何立即在paintGL()中强制Qt重绘QOpenglWidget?
【发布时间】:2020-05-12 08:34:03
【问题描述】:

我想在QOpenGLWidget中绘图,处理数据并在mousePressEvent()函数中调用repaint():

QPoint point[2];
QImage img=QImage(1000,800,QImage::Format_Grayscale8);
void Widget::mousePressEvent(QMouseEvent *event)
{
    point[0]=event->pos();
    point[1]=point[0]+QPoint(10,10);
    repaint();
}

现在在paintGL() 中重新绘制小部件:

void Widget::paintGL()
{  
    vao->release();
    vbo->release();

    QPainter painter;
    painter.begin(image);
    painter.drawLine(point[0],point[1]);
    painter.end();
    painter.begin(this);
    painter.drawImage(0,0,*del->tmpImages[1]);
    painter.beginNativePainting();
    vao->bind();
    vbo->bind();  
    glViewport(0,0,200,200);
    glDrawArrays(GL_TRIANGLE_STRIP,0,8);
    painter.endNativePainting();
    painter.end();
}

我有三个问题。

  1. 为什么我必须释放 vao 和 vbo 才能在 paintGL() 中使用 QPainter 绘制小部件,如果没有,Qpainter 将不起作用。

  2. 同时使用 QPainter 和 OpenGL API 时,widget 无法在 paintGL() 中绘制纹理。直接调用OpenGL API就可以了。

  3. 当我频繁重绘小部件时(频繁点击小部件,调用mousePressEvent()和repaint()),Qt忽略了一些重绘事件。如果调用repaint(),QWidget会立即重绘,所以我该如何强制Qt重绘QOpenGLWidget就像调用repaint()重绘QWidget一样?

【问题讨论】:

  • 不是 Qt OpenGL 大师,但我认为您需要在函数结束时在 vaovbo 上调用 release
  • 我试过了,如果最后调用释放,所有的 OpenGL API 都不起作用。如果在开始时调用 release,则只有纹理不显示。
  • 关于 (3.):为什么要立即重绘?通常,it's better to call QWidget::update than QWidget::repaint (see also this one)。如果您想存储渲染的纹理并且需要所有帧(在屏幕上不可见),您可能更喜欢一些离屏渲染解决方案。

标签: c++ qt


【解决方案1】:

最后,我将 Qpainter 放在 mouseMove() 函数中以在 QImage 上绘图。然后当我开始在图像上绘制时,mouseMove() 将立即在图像上绘制,每个动作都会得到响应,然后在小部件上绘制图像,qt 将不再忽略绘制动作。问题得到解决。但是我仍然没有得到问题二和三的答案。

【讨论】:

    【解决方案2】:

    你调用了initializeOpenGLFunctions()吗? 并且您可能需要重新实现 QOpenGLWidget::paintEvent 并调用 update()?

    【讨论】:

    • 不是这个原因,QOpenGLWidget可以在paintEvent中绘制,但是只能绘制2D图形,我想在paintGL()函数中绘制2D和3D。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 2014-09-25
    • 2015-08-25
    • 2015-12-12
    相关资源
    最近更新 更多