Domanda

Ho derivato da QGLWidget prima, in questo modo:

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

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

   // more stuff...
};

Tuttavia, trovo che se provo a inizializzare un QGraphicsView con il mio QGLWidget personalizzato come viewport, inizializzareGL non viene chiamato (impostando un punto di interruzione all'interno della libreria Qt, nemmeno QGLWidget::initializeGL() quando viene creato semplice).

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

Dov'è la posizione corretta in cui posizionare il codice che attualmente risiede in MyGLWidget::initializeGL()?

È stato utile?

Soluzione 5

Vado avanti e risponderò alla mia stessa domanda.Questo non è ottimale, ma è così che ho aggirato il problema.

Invece di

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

invece ho questo:

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

CustomContext è una classe che deriva da QGLContext.Ho sovrascritto il membro create, in questo modo:

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

        /* do my initialization here */

        doneCurrent();

        return true;
    }

    return false;
}

Non penso che questo sia il modo ottimale per farlo, ma è migliore dell'alternativa di non avere affatto un passaggio di inizializzazione specifico.Sarei comunque felice se qualcuno lasciasse una risposta migliore!

Altri suggerimenti

Lo slot setupViewport di un QGraphicsView personalizzato potrebbe essere utilizzato per chiamare updateGL() sul QGLWidget, che causerà la chiamata a inizializzaGL().

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

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

};

Quindi quello che ho scoperto è che QGraphicsView installa un eventFilter personalizzato sul tuo viewport QGLWidget in modo che non veda mai gli eventi di inizializzazione/ridimensionamento/ridipingimento.Questo probabilmente è stato fatto per farlo funzionare correttamente con drawBackground() ecc.

La mia migliore soluzione attuale è catturare l'evento desiderato in QGraphicsView::resizeEvent()/etc o installare un eventFilter personalizzato sulla classe derivata QGLWidget per catturare gli eventi resize/paint/etc prima che il eventFilter personalizzato di QGraphicsView li inghiottisca.

Il dolore, il dolore,...integrare widget derivati ​​da QGlWidgets in QGraphicsView non è divertente, tra le parti di Qt che conosco questa è sicuramente una delle aree più complicate.Ho finito per usare una parte di kgllib (fuori da kde) chiamato widgetproxy che è un wrapper molto decente attorno a un QGlWidget.L'ho modificato per adattarlo alle mie esigenze, ma funziona abbastanza bene per la maggior parte dei casi generali in cui si desidera utilizzare una classe esistente derivata da QGlWidget all'interno di QGraphicsView e disegnarci sopra altre cose.

initializeGL() non verrò chiamato fino alla prima chiamata a nessuno dei due paintGL() O resizeGL() e non quando il widget viene costruito.Ciò può accadere anche quando il widget viene reso visibile per la prima volta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top