为什么子QGraphicsObject不能正确地重新绘制其背景

时间:2019-03-13 02:42:28

标签: qt

enter image description here

绿色矩形中的QGraphicsObject,它是红色矩形中的QGraphicsObject的父级。

childInRed->setParentItem(this);

当我在绿色矩形中拖动父对象并将其快速移动时,红色矩形中的子对象的背景无法正确地重新绘制。 enter image description here

我知道我可以在父级的mouseMoveEvent中使用update强制子级重新绘制。但这不好,因为我根本不需要重新绘画父母。


#include "asdf.h"
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsView>

#include <QtWidgets>

class CTestGraphicsObject : public QGraphicsObject
{
public:
    QColor m_c;
    CTestGraphicsObject(QColor c)
        : QGraphicsObject(NULL)
        , m_c(c)
    {
        setFlag(QGraphicsItem::ItemIsMovable, true);
        setFlag(QGraphicsItem::ItemIsFocusable, true);
        setFlag(QGraphicsItem::ItemIsSelectable, true);

        auto effect = new QGraphicsDropShadowEffect;
        effect->setOffset(4, 4);
        effect->setBlurRadius(20);

        setGraphicsEffect(effect);
    }
    virtual QRectF boundingRect() const override
    {
        auto rc = QRectF(0, 0, 100, 100);
        return rc;
    }
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        painter->setPen(QPen(m_c));
        painter->drawRect(this->boundingRect());
    }
};

asdf::asdf(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    auto s = new QGraphicsScene(this);
    auto v = new QGraphicsView;
    v->setScene(s);

    CTestGraphicsObject* pParent = new CTestGraphicsObject(Qt::green);
    CTestGraphicsObject* pChild = new CTestGraphicsObject(Qt::red);
    pChild->setParentItem(pParent);
    pChild->setPos(0, 100);
    s->addItem(pParent);
    s->addItem(pChild);

    QVBoxLayout* l = new QVBoxLayout(this->centralWidget());
    l->addWidget(v);
}

asdf::~asdf()
{

}

QGraphicsDropShadowEffect导致此问题,似乎我没有以正确的方式使用它。

1 个答案:

答案 0 :(得分:1)

根据Qt documentation,场景使用边界矩形和区域来定义在更新项目(根据您的情况移动)时要重绘的区域。

如果您的孩子不在其父母的身边,则在重新粉刷时场景会丢失某些部分...

扩展绑定矩形/区域以覆盖其子项。

如果您这样做,它将起作用:

    virtual QRectF boundingRect() const override
    {
        if (this->childrenBoundingRect().isEmpty()) // No children
            return QRectF(0, 0, 100, 100);
        return QRectF(0, 0, 100, 100).united(this->childrenBoundingRect());
    }
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
    {
        painter->setPen(QPen(m_c));
        painter->drawRect(QRectF(0, 0, 100, 100));
    }