4

我以前从 QGLWidget 派生,如下所示:

class MyGLWidget : public QGLWidget
{
public:
   // stuff...

   virtual void initializeGL() { /* my custom OpenGL initialization routine */ }

   // more stuff...
};

但是,我发现如果我尝试使用我的自定义 QGLWidget 作为视口来初始化 QGraphicsView,则不会调用 initializeGL(在 Qt 库中设置断点,QGLWidget::initializeGL() 在创建时也不会被调用)。

// initializeGL, resizeGL, paintGL not called
ui.graphicsView->setViewport(new MyGLWidget(QGLFormat(QGL::DoubleBuffer)));

// initializeGL, resizeGL, paintGL *still* not called
ui.graphicsView->setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer)));

放置当前驻留在 MyGLWidget::initializeGL() 中的代码的正确位置在哪里?

4

5 回答 5

4

自定义 QGraphicsView 的 setupViewport 插槽可用于调用 QGLWidget 上的 updateGL(),这将导致调用 initializeGL()。

class MyGraphicsView : public QGraphicsView
{
    //... The usual stuff

protected slots:
    virtual void setupViewport(QWidget *viewport)
    {
        QGLWidget *glWidget = qobject_cast<QGLWidget*>(viewport);
        if (glWidget)
            glWidget->updateGL();
    }

};
于 2010-03-24T09:10:53.603 回答
2

所以我发现 QGraphicsView 在您的 QGLWidget 视口上安装了一个自定义事件过滤器,因此它永远不会看到初始化/调整大小/重绘事件。这样做可能是为了使其与 drawBackground() 等一起正常工作。

我目前的最佳解决方案是在 QGraphicsView::resizeEvent()/etc 中捕获所需的事件,或者在 QGLWidget 派生类上安装自定义 eventFilter 以在 QGraphicsView 的自定义 eventFilter 吞噬它们之前捕获 resize/paint/etc 事件。

于 2009-11-16T23:41:02.783 回答
1

痛苦,痛苦,......将源自 QGlWidgets 的小部件集成到 QGraphicsView 中并不好玩,我知道这绝对是 Qt 的一部分,这绝对是更混乱的领域之一。我最终使用了名为 widgetproxy 的kgllib(kde 之外)的一部分,它是一个非常不错的 QGlWidget 包装器。我对其进行了修改以满足我的需要,但对于大多数一般情况下,您想在 QGraphicsView 中使用从 QGlWidget 派生的现有类并在其上绘制其他东西的情况相当好。

于 2009-07-12T03:49:44.573 回答
0

initializeGL()直到第一次调用或者paintGL()构造resizeGL()小部件时才会调用。这可能会在小部件首次可见时发生。

于 2009-07-10T22:56:22.797 回答
0

我将继续回答我自己的问题。这不是最佳的,但这就是我解决问题的方法。

代替

ui.graphicsView->setViewport(new MyGLWidget(QGLFormat(QGL::DoubleBuffer)));

我有这个:

ui.graphicsView->setViewport(new QGLWidget(new CustomContext(QGLFormat(QGL::SampleBuffers))));

CustomContext 是一个派生自 QGLContext 的类。我已经覆盖了 create 成员,如下所示:

virtual bool create(const QGLContext *shareContext = 0)
{
    if(QGLContext::create(shareContext))
    {
        makeCurrent();

        /* do my initialization here */

        doneCurrent();

        return true;
    }

    return false;
}

我不认为这是执行此操作的最佳方法,但它比完全没有特定初始化步骤的替代方法要好。我仍然很高兴有人留下更好的答案!

于 2009-08-03T19:01:35.780 回答