我正在尝试使用QOpenGLWidget而不进行子类化。

当我尝试在QOpenGLWidget的方法或信号之外进行OpenGL调用时,似乎什么也没发生。例如,尽管我设置了glClearColor,以下代码仍清除了黑色窗口:

MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
{
    auto glw = new QOpenGLWidget( this );
    glw->makeCurrent();
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glw->doneCurrent();

    connect( glw, &QOpenGLWidget::aboutToCompose, [=] {
        glClear( GL_COLOR_BUFFER_BIT );
    });

    setCentralWidget( glw );
}


但是,当我在连接到glClearColor信号的lambda内移动aboutToCompose时,小部件被清除为白色。

最佳答案

正如Fabio和G.M.的注释部分所基本解释的那样,如果QOpenGLWidget::makeCurrent在未进行足够的设置之前被调用,将无法工作。

从Qt 5.11以及可能的其他发行版开始,QOpenGLWidget::makeCurrent通过调用QOpenGLContext::makeCurrent方法工作。但是,仅当QOpenGLWidget已处于初始化状态时,才发生该调用。此外,QOpenGLContext::makeCurrent可能会失败。后者至少通过其bool返回参数给出了一些故障指示。不幸的是,QOpenGLWidget::makeCurrent完全没有给出任何指示。 QOpenGLWidget::makeCurrent静默失败。

除了了解这一点并注意注释中的建议之外,还可以使用QOpenGLWidget::context方法来确定QOpenGLWidget是否处于初始化状态。根据链接的文档(在实践中可以看到),context方法返回“ 0(如果尚未初始化)”,否则返回非null指针。因此,这是确定QOpenGLWidget::makeCurrent是否调用QOpenGLContext::makeCurrent的方法,也是部分解决QOpenGLWidget::makeCurrent返回void的方法。在这种情况下,这可能不是特别有用,但是在其他相关上下文中可能有用,因此我认为值得一提。

因此,要使QOpenGLWidget::makeCurrent真正成功,必须在QOpenGLWidget::makeCurrent初始化后调用QOpenGLWidget才能使它起作用。

仔细阅读该问题的内容,听起来似乎想知道要使GL调用正常工作需要做什么。正如问题的作者所认识到的那样,将GL调用延迟到触发aboutToCompose信号之前,可以解决此问题(至少在该用户代码的上下文中)。另一种方法是使QOpenGLWidget可见,然后调用GL代码。

希望这能至少完全有效地回答您的问题。

08-16 00:52