Pergunta

Já derivei do qglwidget antes, como assim:

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

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

   // more stuff...
};

No entanto, acho que se eu tentar inicializar um QGraphicsView com meu qglWidget personalizado como a viewport, o InitializeGL não é chamado (definindo um ponto de interrupção na biblioteca QT, nem o QGLWidget :: InitializeGL () quando criado com planície).

// 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)));

Onde está o local correto para colocar o código que atualmente reside no myglwidget :: InitializeGL ()?

Foi útil?

Solução 5

Vou seguir em frente e responder minha própria pergunta. Isso não é ideal, mas foi assim que eu tive o problema.

Ao invés de

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

Eu tenho isso em vez disso:

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

O CustomContext é uma classe que deriva do QGLContext. Eu substituí o membro Criar, como assim:

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

        /* do my initialization here */

        doneCurrent();

        return true;
    }

    return false;
}

Eu não acho que essa seja a maneira ideal de fazer isso, mas é melhor do que a alternativa de não ter uma etapa de inicialização específica. Eu ainda ficaria feliz por alguém deixar uma resposta melhor!

Outras dicas

O slot SetupViewPort de um qGraphicsView personalizado pode ser usado para ligar para o UpdateL () no QGLWidget, que fará com que o InitializeGL () seja chamado.

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

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

};

Então, o que eu encontrei é que o QGraphicsView instala um EventFilter personalizado na sua viewport QGLWidget, para que ele nunca veja os eventos inicialize/redimensione/repintar. Provavelmente, isso foi feito para fazê -lo funcionar corretamente com o Drawbackground () etc.

Minha melhor resolução atual é capturar o evento desejado no QGRAPHICSVIEW :: REDIMEVEVENT ()/etc ou instalar um EventFilter personalizado na sua classe derivada de QGLWidget para capturar os eventos redimensionados/tinta/etc antes que os eventos personalizados do QGRAPHICSVIEW os enxugem.

A dor, a dor, ... integrando os widgets derivados de qglWidgets no QGraphicsView não é divertido, das partes do QT que eu sei que essa é definitivamente uma das áreas mais confusas. Acabei usando uma parte de kgllib (fora de KDE) chamado widgetproxy que é um invólucro muito decente em torno de um qglwidget. Modifiquei -o para atender às minhas necessidades, mas funciona razoavelmente bem para os casos mais gerais em que você deseja usar uma classe existente derivada do QGLWidget dentro de uma View QGraphics e desenhar outras coisas sobre ela.

initializeGL() não será chamado até a primeira chamada para paintGL() ou resizeGL() e não quando o widget é construído. Isso pode acontecer tão tarde quanto quando o widget é tornado visível pela primeira vez.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top