2012-06-15 8 views
7

QGraphicsSceneに、私はその上に2,sのバックグラウンドを設定しました。これらのグラフィックアイテムは任意の形状です。別のQGraphicsItem、つまりサークルを作成して、これらのアイテムの上に配置すると、色で塗りつぶされるのではなく、このサークル内の背景が基本的に表示されます。QGraphicsItemを作成するには、QGraphicsSceneの背景を表示しますか?

これは、Photoshopの上に複数のレイヤーを持つ背景のようなものです。円形マーキーツールを使用して、背景の上にあるすべてのレイヤーを削除し、サークル内の背景を表示します。

また、別の方法として、不透明度を設定することもできますが、この不透明度は背景を表示するために直接下の項目(楕円内のみ)に影響します。

+1

リアルタイム描画が「プッシュバック」オブジェクトと呼ばれるもので、これを一般化と呼ばれる私が使用したプログラム。非常に便利ですが、同様の一般化の使用を検討することもできます。http://www.mediachance.com/realdraw/help/index.html?pushback.htm – HostileFork

答えて

7

次のように動作する可能性があります。基本的には、通常のQGraphicsSceneを背景にレンダリングする機能があります。QPainterです。次に、あなたの「カットアウト」グラフィックアイテムは、シーンの背景を他のアイテムの上にレンダリングするだけです。これが機能するためには、切り抜かれたアイテムは最高のZ値を持たなければなりません。

screen shot

#include <QtGui> 

class BackgroundDrawingScene : public QGraphicsScene { 
public: 
    explicit BackgroundDrawingScene() : QGraphicsScene() {} 
    void renderBackground(QPainter *painter, 
         const QRectF &source, 
         const QRectF &target) { 
    painter->save(); 
    painter->setWorldTransform(
      QTransform::fromTranslate(target.left() - source.left(), 
            target.top() - source.top()), 
      true); 
    QGraphicsScene::drawBackground(painter, source); 
    painter->restore(); 
    } 
}; 

class CutOutGraphicsItem : public QGraphicsEllipseItem { 
public: 
    explicit CutOutGraphicsItem(const QRectF &rect) 
    : QGraphicsEllipseItem(rect) { 
    setFlag(QGraphicsItem::ItemIsMovable); 
    } 
protected: 
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { 
    BackgroundDrawingScene *bgscene = 
     dynamic_cast<BackgroundDrawingScene*>(scene()); 
    if (!bgscene) { 
     return; 
    } 

    painter->setClipPath(shape()); 
    bgscene->renderBackground(painter, 
           mapToScene(boundingRect()).boundingRect(), 
           boundingRect()); 
    } 
}; 


int main(int argc, char **argv) { 
    QApplication app(argc, argv); 

    BackgroundDrawingScene scene; 
    QRadialGradient gradient(0, 0, 10); 
    gradient.setSpread(QGradient::RepeatSpread); 
    scene.setBackgroundBrush(gradient); 

    scene.addRect(10., 10., 100., 50., QPen(Qt::SolidLine), QBrush(Qt::red)); 
    scene.addItem(new CutOutGraphicsItem(QRectF(20., 20., 20., 20.))); 

    QGraphicsView view(&scene); 
    view.show(); 

    return app.exec(); 
} 
+0

Dave、ありがとうございます。このコードはかなり面白いです。楕円を動かすためにそれを変更できますか?私は 'setFlag(QGraphicsItem :: ItemIsMovable、true)とsetFlag(QGraphicsItem :: ITemIsSelectable、true)'を使用して近づき、送信前に 'mapToScene(shape())'と 'mapToScene(rect())'を使用しました。これらのパラメータは 'renderBackground'関数に渡しますが、それは少しです。私はあなたのコードを今夜後でもっと詳しく調べます。再度、感謝します。 – Justin

+0

私はまだ運がありません。上記を行うと、 'paint'関数はアイテムがドラッグされたときに変更されないアイテム座標を使用するので、アイテムをバックグラウンドから外しているようです。 'renderBackground'関数を呼び出した後にペインタオブジェクトを翻訳する方法はありますか? – Justin

+0

ああ、私は問題を見る。上記のコードはアイテムの位置を処理していません。 (シーンに追加する前に 'setPos()'を呼び出すと同じ問題が発生するでしょう)私は現在どのコードをテストする場所ではありませんが、Qtのソースコードがあれば'QGraphicsScene :: render()'メソッドをチェックしてください。私は彼らが一時的にペインターの変換を逆にして、ペイントしてから、変換を元に戻すと確信しています。申し訳ありませんが、今私はそれで作業することはできません。あなたがまだ立ち往生している場合は、明日または月曜日にソリューションを投稿しようとします! –

関連する問題