Qt Widgets:QGraphicsEffect::drawSource()の基礎から応用までを網羅!これであなたもグラフィックエフェクトマスターに


QGraphicsEffect::drawSource() は、Qt Widgets ライブラリで提供される QGraphicsEffect クラスの保護されたメンバ関数であり、グラフィック効果のソースを直接描画するために使用されます。この関数は、QGraphicsEffect::draw() 関数内で呼び出され、効果が適用されるアイテムの元の外観を描画します。

構文

void QGraphicsEffect::drawSource(QPainter *painter);

引数

  • painter: 効果を描画するために使用する QPainter オブジェクトへのポインタ

戻り値

なし

詳細

QGraphicsEffect::drawSource() 関数は、効果のソースを直接描画するために使用されます。これは、効果が透明度やぼかしなどの視覚効果を適用する前に、ソースアイテムの元の外観をレンダリングする必要がある場合に役立ちます。

この関数は、QGraphicsEffect::draw() 関数内で呼び出されます。draw() 関数は、効果がレンダリングされるたびに呼び出される仮想関数です。この関数内で、drawSource() 関数を呼び出してソースを描画し、必要に応じて効果を適用することができます。

次の例では、QGraphicsOpacityEffect クラスを使用してアイテムの透明度を下げるカスタム効果を作成する方法を示します。この効果は、drawSource() 関数を呼び出してソースアイテムを直接描画し、その後、setOpacity() メソッドを使用して透明度を設定します。

class MyOpacityEffect : public QGraphicsEffect
{
public:
    void draw(QPainter *painter) override
    {
        drawSource(painter);
        painter->setOpacity(m_opacity);
    }

    void setOpacity(qreal opacity)
    {
        if (opacity != m_opacity) {
            m_opacity = opacity;
            update();
        }
    }

private:
    qreal m_opacity = 1.0;
};

この例では、MyOpacityEffect クラスは QGraphicsEffect クラスから派生しています。draw() 関数は、drawSource() 関数を呼び出してソースアイテムを直接描画し、その後、setOpacity() メソッドを使用して透明度を設定します。

setOpacity() メソッドは、効果の透明度を設定するために使用されます。引数の opacity は、0.0 (完全に透明) から 1.0 (完全に不透明) までの範囲の値である必要があります。

この効果をアイテムに適用するには、次のコードを使用します。

QGraphicsItem *item = ...;
MyOpacityEffect *effect = new MyOpacityEffect;
effect->setOpacity(0.5);
item->setGraphicsEffect(effect);

このコードは、item アイテムの透明度を 50% に設定します。

  • 効果が透明である場合 (opacity が 0.0 に設定されている場合)、drawSource() 関数を呼び出す必要はありません。
  • QGraphicsEffect::drawSource() 関数は、効果のソースがピクセルマップである場合にのみ効率的に動作します。ソースが他のタイプのアイテムである場合は、sourcePixmap() 関数を使用してピクセルマップを取得してから描画する必要があります。


例 1: 透明度効果

この例では、QGraphicsOpacityEffect クラスを使用してアイテムの透明度を下げるカスタム効果を作成する方法を示します。

class MyOpacityEffect : public QGraphicsEffect
{
public:
    void draw(QPainter *painter) override
    {
        drawSource(painter);
        painter->setOpacity(m_opacity);
    }

    void setOpacity(qreal opacity)
    {
        if (opacity != m_opacity) {
            m_opacity = opacity;
            update();
        }
    }

private:
    qreal m_opacity = 1.0;
};

このコードは、MyOpacityEffect クラスという新しいクラスを作成します。このクラスは QGraphicsEffect クラスから派生しており、draw() メソッドと setOpacity() メソッドをオーバーライドしています。

draw() メソッドは、drawSource() 関数を呼び出してソースアイテムを直接描画し、その後、setOpacity() メソッドを使用して透明度を設定します。

QGraphicsItem *item = ...;
MyOpacityEffect *effect = new MyOpacityEffect;
effect->setOpacity(0.5);
item->setGraphicsEffect(effect);

例 2: ぼかし効果

この例では、QGraphicsBlurEffect クラスを使用してアイテムをぼかすカスタム効果を作成する方法を示します。

class MyBlurEffect : public QGraphicsEffect
{
public:
    void draw(QPainter *painter) override
    {
        // ぼかし効果を適用する前にソースを描画する
        drawSource(painter);

        // ぼかし効果を適用する
        painter->setRenderHint(QPainter::Antialiasing);
        painter->save();
        painter->translate(-m_blurRadius, -m_blurRadius);
        painter->setOpacity(m_opacity);
        drawSource(painter);
        painter->restore();
    }

    void setBlurRadius(qreal radius)
    {
        if (radius != m_blurRadius) {
            m_blurRadius = radius;
            update();
        }
    }

    void setOpacity(qreal opacity)
    {
        if (opacity != m_opacity) {
            m_opacity = opacity;
            update();
        }
    }

private:
    qreal m_blurRadius = 5.0;
    qreal m_opacity = 1.0;
};

このコードは、MyBlurEffect クラスという新しいクラスを作成します。このクラスは QGraphicsEffect クラスから派生しており、draw() メソッドと setBlurRadius() メソッドと setOpacity() メソッドをオーバーライドしています。

draw() メソッドは、次の手順を実行します。

  1. ぼかし効果を適用する前にソースを描画します。
  2. ぼかし効果を適用します。
  3. 効果の透明度を設定します。
  4. ソースをもう一度描画します。

setBlurRadius() メソッドは、効果のぼかし半径を設定するために使用されます。引数の radius は、ピクセル単位の値である必要があります。

QGraphicsItem *item = ...;
MyBlurEffect *effect = new MyBlurEffect;
effect->setBlurRadius(10.0);
effect->setOpacity(0.7);
item->setGraphicsEffect(effect);

このコードは、item アイテムを 10 ピクセルぼかし、透明度を 70% に設定します。



しかし、drawSource() 関数はいくつかの制限があります。

  • 効果が透明である場合 (opacity が 0.0 に設定されている場合)、drawSource() 関数を呼び出す必要はありません。
  • 効果のソースがピクセルマップである場合にのみ効率的に動作します。ソースが他のタイプのアイテムである場合は、sourcePixmap() 関数を使用してピクセルマップを取得してから描画する必要があります。

これらの制限を回避するために、drawSource() 関数の代替方法を使用することができます。

代替方法 1: QPainter::beginPath()QPainter::endPath() を使用してソースを描画する

この方法は、効果のソースがパスである場合に役立ちます。

void draw(QPainter *painter) override
{
    // ソースパスを描画する
    painter->beginPath();
    drawSource(painter);
    painter->endPath();

    // 効果を適用する
    // ...
}

このコードは、drawSource() 関数を呼び出してソースパスを描画してから、効果を適用します。

代替方法 2: QGraphicsItem::itemTransform() を使用してソースをレンダリングする

この方法は、効果のソースがアイテムである場合に役立ちます。

void draw(QPainter *painter) override
{
    // ソースアイテムをレンダリングする
    QGraphicsItem *sourceItem = sourceItem();
    if (sourceItem) {
        QPainterPath path = sourceItem->itemTransform(view->viewportTransform());
        painter->save();
        painter->clipPath(path);
        sourceItem->paint(painter, view);
        painter->restore();
    }

    // 効果を適用する
    // ...
}

このコードは、sourceItem() メソッドを使用してソースアイテムを取得し、itemTransform() メソッドを使用してビューポート座標系に変換します。次に、clipPath() メソッドを使用してソースアイテムの形状にクリップし、paint() メソッドを使用してソースアイテムを描画します。

この方法は、複雑な効果を作成する必要がある場合に役立ちます。

カスタムレンダリングエンジンを使用するには、QGraphicsEffect::customRender() メソッドをオーバーライドする必要があります。このメソッドは、効果がレンダリングされるときに呼び出されます。

void customRender(QPainter *painter, QRectF sourceRect) override
{
    // ソースを描画する
    // ...

    // 効果を適用する
    // ...
}

このコードは、sourceRect 引数を使用してソースの境界四角形を取得し、ソースを描画してから効果を適用します。

QGraphicsEffect::drawSource() 関数は、グラフィック効果のソースを描画するための便利な方法ですが、いくつかの制限があります。これらの制限を回避するために、代替方法を使用することができます。

どの代替方法を使用するかは、効果の要件によって異なります。

  • 複雑な効果を作成する必要がある場合は、カスタムレンダリングエンジンを使用します。
  • 効果のソースがアイテムである場合は、QGraphicsItem::itemTransform() を使用してソースをレンダリングします。
  • 効果のソースがパスである場合は、QPainter::beginPath()QPainter::endPath() を使用してソースを描画します。