вызывая Qt QGraphicsView :: setViewport с пользовательским QGLWidget - PullRequest
4 голосов
/ 11 июля 2009

Я получил от QGLWidget и так:

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

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

   // more stuff...
};

Однако я обнаружил, что если я попытаюсь инициализировать QGraphicsView с моим пользовательским QGLWidget в качестве окна просмотра, 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 ]

4 голосов
/ 24 марта 2010

Слот setupViewport пользовательского QGraphicsView можно использовать для вызова updateGL () в QGLWidget, что приведет к вызову 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 голосов
/ 17 ноября 2009

Итак, я обнаружил, что QGraphicsView устанавливает пользовательский eventFilter в область просмотра QGLWidget, поэтому он никогда не видит события инициализации / изменения размера / перерисовки. Вероятно, это было сделано для правильной работы с drawBackground () и т. Д.

Мое текущее лучшее решение - перехватить желаемое событие в QGraphicsView :: resizeEvent () / etc или установить собственный eventFilter в свой производный класс QGLWidget, чтобы перехватить события resize / paint / etc, прежде чем пользовательский eventFilter QGraphicsView поглотит их.

1 голос
/ 12 июля 2009

Боль, боль, ... интеграция виджетов, полученных из QGlWidgets, в QGraphicsView - неинтересная часть Qt, которую я знаю, это определенно одна из самых грязных областей. В итоге я использовал часть kgllib (вне kde) под названием widgetproxy, которая является очень приличной оболочкой для QGlWidget. Я изменил его в соответствии со своими потребностями, но достаточно хорошо работает для большинства общих случаев, когда вы хотите использовать существующий класс, производный от QGlWidget внутри QGraphicsView, и рисовать другие вещи поверх него.

0 голосов
/ 03 августа 2009

Я собираюсь пойти дальше и ответить на свой вопрос. Это не оптимально, но так я обошёл проблему.

Вместо

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

Я не думаю, что это оптимальный способ сделать это, но это лучше, чем альтернатива вообще не иметь определенного шага инициализации. Я все равно был бы рад, если бы кто-то оставил лучший ответ!

0 голосов
/ 11 июля 2009

initializeGL() не будет вызван до первого вызова paintGL() или resizeGL(), а не после создания виджета. Это может произойти уже тогда, когда виджет впервые становится видимым.

...