4

次のように、以前に 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() に存在するコードを配置する正しい場所はどこですか?

4

5 に答える 5

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

};
于 2010-03-24T09:10:53.603 に答える
2

だから私が見つけたのは、 QGraphicsView が QGLWidget ビューポートにカスタム eventFilter をインストールするので、初期化/サイズ変更/再描画イベントが表示されないことです。これはおそらく、drawBackground() などで適切に動作させるために行われたものです。

私の現在の最善の解決策は、QGraphicsView::resizeEvent()/etc で目的のイベントをキャッチするか、QGLWidget 派生クラスにカスタム eventFilter をインストールして、QGraphicsView のカスタム eventFilter が飲み込む前に resize/paint/etc イベントをキャッチすることです。

于 2009-11-16T23:41:02.783 に答える
1

苦痛、苦痛、... QGlWidgets から派生したウィジェットを QGraphicsView に統合することは楽しくありません。これは間違いなく厄介な領域の 1 つであることがわかっている Qt の部分です。QGlWidgetの非常にまともなラッパーであるwidgetproxyと呼ばれるkgllib(kdeの外)一部を使用することになりました。ニーズに合わせて変更しましたが、QGraphicsView 内で QGlWidget から派生した既存のクラスを使用し、その上に他のものを描画するほとんどの一般的なケースではかなりうまく機能します。

于 2009-07-12T03:49:44.573 に答える
0

私は先に進み、私自身の質問に答えます。これは最適ではありませんが、これが私が問題を回避した方法です。

それ以外の

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

これが最適な方法だとは思いませんが、特定の初期化手順をまったく行わないという代替案よりはましです。誰かがより良い答えを残してくれるとうれしいです!

于 2009-08-03T19:01:35.780 に答える