2

かなり珍しい状況があります-子ウィジェットを持つウィジェットがあり、Qt 5ペイントシステムをバイパスして、親が子のペイントを行う必要があります。詳細: OpenGL コンテキストを持つ QWidget があり、通常の paintEvent() で描画を行います。

    mRenderer->activate();
    mRenderer->preRender();
    mRenderer->setClearColor(Color(0.75f));
    mRenderer->clear(Renderer::CLEAR_Color);

    QList<RendererWidgetWrapper *> wrappers = findChildren<RendererWidgetWrapper *>();
    foreach (RendererWidgetWrapper *wrapper, wrappers)
        wrapper->paint();

    mRenderer->postRender();

ここで、mRenderer は OpenGL (またはその他の可能な 3D レンダラー) のラッパーです。子に対して明示的に paint() を呼び出すことに注意してください。この paint() 関数は、mRenderer を使用していくつかのものをレンダリングするだけなので、通常の Qt ペイント パイプラインをバイパスします。親ウィジェットにはいくつかの属性が設定されています。

    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_NoSystemBackground);
    setAttribute(Qt::WA_OpaquePaintEvent);
    setAttribute(Qt::WA_PaintUnclipped);

nullptr を QPaintEngine として返します。子も QPaintEngine として nullptr を返しますが、Qt::WA_NoSystemBackground と Qt::WA_OpaquePaintEvent 以外の属性を設定しません。要するに、すべては、多くのコンテキストでシステムを強制終了することを避けるために、何百ものウィジェットを親が所有する 1 つの OpenGL コンテキストにレンダリングする方法です。この方法の問題点は、子供たちが全員黒人であることです。何かが可視領域をクリアしており、この黒さを消す方法がわかりません。誰かがそれをどうするか考えていますか?

編集:

setUpdatesEnabled(false); の使用 黒い背景を削除しましたが、子ウィジェットの領域は更新されません。代わりに、以前に画面に表示されていたものが含まれます。

編集2:

親に Qt::WA_PaintOnScreen 属性がある場合、Qt がネイティブの子ウィンドウを作成し、問題が発生することがわかりました。では、問題は、親を強制的にネイティブ ウィンドウにしながら、それを回避する方法です。

4

1 に答える 1

0

子供のペイントイベントをバイパスしたい場合は、再実装できます

virtual void    paintEvent ( QPaintEvent * event );

彼らのために。そのように:

.h

class QWidgetNoPaintEvent : public QWidget
{
   //reimplement all ctors here
   virtual void paintEvent ( QPaintEvent * event );
}

.cpp

void QWidgetNoPaintEvent::paintEvent ( QPaintEvent * event )
{
 //do nothing, or reject event, or do something custom ???
}

QWidgetNoPaintEventから継承されたウィジェットのQtを介したペイントイベントのみをブロックするため、他の問題が解決するかどうかは100%わかりません。

于 2013-04-25T20:28:11.107 に答える