代码之家  ›  专栏  ›  技术社区  ›  moswald Jarod42

使用自定义qglwidget调用qt的qgraphicsView::setViewport

  •  4
  • moswald Jarod42  · 技术社区  · 16 年前

    我以前从qglwidget派生过,比如:

    class MyGLWidget : public QGLWidget
    {
    public:
       // stuff...
    
       virtual void initializeGL() { /* my custom OpenGL initialization routine */ }
    
       // more stuff...
    };
    

    但是,我发现,如果我尝试用自定义的qglwidget作为视区初始化qgraphicsView,则不会调用initializegl(在qt库中设置断点,创建plain时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 回复  |  直到 16 年前
        1
  •  4
  •   Kuba hasn't forgotten Monica    10 年前

    自定义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();
        }
    
    };
    
        2
  •  2
  •   NuShrike    15 年前

    因此,我发现qgraphicsView在qglwidget视区上安装了一个自定义事件过滤器,这样它就不会看到初始化/调整大小/重新绘制事件。这样做可能是为了使它能够正确地与defectground()等一起工作。

    我当前的最佳解决方案是在qgraphicsView::ResizeEvent()/etc中捕获所需的事件,或者在qglwidget派生类上安装自定义事件过滤器,以便在qgraphicsView的自定义事件过滤器吞没它们之前捕获Resize/Paint/etc事件。

        3
  •  1
  •   Harald Scheirich    16 年前

    痛苦,痛苦,…将从qglwidgets派生的widgets集成到qgraphicsView中并不有趣,我知道qt的某些部分肯定是比较麻烦的部分之一。我最终使用了 kgllib (在kde之外)称为widgetproxy,它是围绕qglwidget的一个非常好的包装器。我修改了它以满足我的需要,但在大多数一般情况下,如果您想在QgraphicsView中使用从QGLwidget派生的现有类,并在其上绘制其他内容,则可以很好地工作。

        4
  •  0
  •   Troubadour    16 年前

    initializeGL() 直到第一个电话 paintGL() resizeGL() 而不是在构建小部件时。这可能最迟在小部件首次可见时发生。

        5
  •  0
  •   moswald Jarod42    16 年前

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

    而不是

    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;
    }
    

    我不认为这是实现这一点的最佳方法,但它比完全没有特定初始化步骤的替代方法要好。我还是很高兴有人能留下更好的答案!

    推荐文章