如何使QGraphicsItem显示QGraphicsScene中的背景?
在QGraphicsScene
中,我有一个背景,在其上面有几个QGraphicsItem
。这些图形项目是任意形状的。我想制作另一个QGraphicsItem,即一个圆形,当放置在这些项目上时,将基本显示该圆形内的背景,而不是填充颜色。如何使QGraphicsItem显示QGraphicsScene中的背景?
这将有点像在Photoshop的顶部它有多层的背景。然后,使用圆形选框工具删除背景顶部的所有图层,以显示圆圈内的背景。
或者,查看它的另一种方式可能是设置不透明度,但这种不透明度会影响正下方的项目(但仅限于椭圆内)以显示背景。
以下可能有效。它基本上扩展了一个正常的QGraphicsScene
,只能渲染它的背景到任何QPainter
。然后,您的“剪切”图形项目只会将场景背景渲染到其他项目的顶部。为此,切出的项目必须具有最高的Z值。
#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();
}
Dave,非常感谢。这段代码非常有趣。你可以修改它,让椭圆移动?在发送之前,我使用'setFlag(QGraphicsItem :: ItemIsMovable,true)和setFlag(QGraphicsItem :: ITemIsSelectable,true)'并且还使用了'mapToScene(shape())'和'mapToScene(rect())'这些参数到'renderBackground'函数,但它有点关闭。今晚晚些时候我会更详细地研究你的代码。再次感谢。 – Justin
好了,所以我仍然没有任何运气...当我这样做时,它似乎将背景从项目转换,因为'paint'函数使用项目坐标,当项目被拖动时不会改变。有没有办法在调用'renderBackground'函数后翻译画家对象? – Justin
哦,是的,我看到了问题。上面的代码不处理该项目的位置。 (如果在将项目添加到场景之前调用'setPos()',您可能会遇到同样的问题。)我现在不在某个地方测试任何代码,但是如果您有Qt的源代码,检查'QGraphicsScene :: render()'方法。我敢打赌,他们暂时扭转了画家的转变,做了油漆,然后恢复了转变。对不起,我现在无法处理它。如果您仍然陷入困境,我会尽量在明天或周一发布解决方案! –
的程序,我用所谓的实时绘制所谓的“推背”对象概括这一点。相当有用,你可以考虑使用类似的泛化:http://www.mediachance.com/realdraw/help/index.html?pushback.htm – HostileFork