gpt4 book ai didi

qt - QGraphicsItem::itemChange 通知位置更改而不是大小更改

转载 作者:行者123 更新时间:2023-12-04 13:18:57 32 4
gpt4 key购买 nike

我有一个派生自 QGraphicsEllipseItem 的类,我需要知道它的位置或大小何时发生任何变化。我用鼠标调整大小并调用 QGraphicsEllipse::setRect。

好的,所以我尽职尽责地覆盖了类中的 itemChange() 方法,然后在创建它后小心地设置了 ItemSendsGeometryChanges 标志

// Returns a human readable string for any GraphicsItemChange enum value

inline std::string EnumName(QGraphicsItem::GraphicsItemChange e);

// Simple test ellipse class

class MyEllipse : public QGraphicsEllipseItem
{
public:
MyEllipse(int x, int y, int w, int h) : QGraphicsEllipseItem(x, y, w, h)
{
setFlags(
QGraphicsItem::ItemIsSelectable
| QGraphicsItem::ItemIsMovable
| QGraphicsItem::ItemSendsGeometryChanges);
}


// QGraphicItem overrides
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override
{
std::stringstream oss;
oss << "ItemChange " << EnumName(change) << std::endl;
OutputDebugString(oss.str().c_str());
return __super::itemChange(change, value);
}
};

我的主要代码创建其中之一,将其添加到场景中,然后尝试移动/调整其大小。

虽然我在椭圆上调用 setPos() 后总是收到通知,但在调用 setRect() 后我没有收到通知。我可以使用 setRect 来完全改变椭圆的几何形状,但我的 itemChange 覆盖从未被调用。没有任何标志。

现在显然改变项目的矩形正在改变它的几何形状,那么我错过了什么?

我应该设置其他标志吗?改变我应该使用的椭圆大小的其他方法?我可以覆盖其他一些虚拟通知?

最佳答案

问题是QGraphicsItem的位置与QGraphicsEllipseItem无关的矩形。第一个是项目相对于它的父项目的位置,或者,如果它是 NULL ,到它的场景。最后一个是矩形相对到项目位置 应该画椭圆的地方。现场及QGraphicsItem的核心不知道它的任何变化。

我们来看看这个测试:

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

QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsEllipseItem item(10, 20, 30, 40);
scene.addItem(&item);

qDebug() << item.pos() << item.scenePos() << item.boundingRect();
item.setRect(110, 120, 30, 40);
qDebug() << item.pos() << item.scenePos() << item.boundingRect();

view.resize(500, 500);
view.show();

return app.exec();
}

输出是:
QPointF(0,0) QPointF(0,0) QRectF(9.5,19.5 31x41)
QPointF(0,0) QPointF(0,0) QRectF(109.5,119.5 31x41)

可能的出路:
  • 使用 setTransform .转换矩阵的变化由标准跟踪 QGraphicsitem s 和 itemChange会收到相应的变化。但我猜非同一矩阵会降低性能(未检查)。
  • 实现您自己的功能,如 setRect您将在其中手动跟踪几何变化。
  • 子类 QGraphicsItem ,不是 QGraphicsEllipseItem .在这种情况下,您可以防止无法跟踪的几何更改,因为它们是通过您的规则执行的。它看起来像这样:
    class EllipseItem: public QGraphicsItem
    {
    public:
    // Here are constructors and a lot of standard things for
    // QGraphicsItem subclassing, see Qt Assistant.
    ...

    // This method is not related with QGraphicsEllipseItem at all.
    void setRect(const QRectF &newRect)
    {
    setPos(newRect.topLeft());
    _width = newRect.width();
    _height = newRect.height();
    update();
    }

    QRectF boundingRect() const override
    {
    return bRect();
    }

    void paint(QPainter * painter, const QStyleOptionGraphicsItem * option,
    QWidget * widget = nullptr) override
    {
    painter->drawRect(bRect());
    }

    private:
    qreal _width;
    qreal _height;

    QRectF bRect() const
    {
    return QRectF(0, 0, _width, _height);
    }
    };

    您还应该跟踪项目转换和移动 QGraphicsItem::itemChange .
  • 关于qt - QGraphicsItem::itemChange 通知位置更改而不是大小更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40162720/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com