使用自定义QGLWidget调用Qt的QGraphicsView :: setViewport

时间:2009-07-10 21:48:01

标签: qt opengl qgraphicsview qglwidget

之前我从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()中的代码的正确位置在哪里?

5 个答案:

答案 0 :(得分: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();
    }

};

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

痛苦,痛苦,......将QGlWidgets派生的小部件整合到QGraphicsView中并不好玩,Qt的各个部分我知道这绝对是一个混乱的领域。我最终使用名为widgetproxy的kgllib(在kde之外)的一部分,这是一个围绕QGlWidget的非常好的包装器。我修改它以满足我的需要,但是对于大多数一般情况你要使用QGlWicsView中的QGlWidget派生的现有类并在其上绘制其他东西时效果相当好。

答案 3 :(得分:0)

在第一次调用initializeGL()paintGL()之前,

resizeGL()将不会被调用,而不是在构建小部件时调用。这可能发生在窗口小部件首次可见时。

答案 4 :(得分:0)

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

而不是

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

我得到了这个:

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

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

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

        /* do my initialization here */

        doneCurrent();

        return true;
    }

    return false;
}

我认为这不是最佳方法,但它比没有特定初始化步骤的替代方案更好。我仍然很乐意让别人留下更好的答案!