我有一个从 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);
}
};
Run Code Online (Sandbox Code Playgroud)
我的主代码创建其中之一,将其添加到场景中,然后尝试移动/调整其大小。
虽然我在椭圆上调用 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();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
QPointF(0,0) QPointF(0,0) QRectF(9.5,19.5 31x41)
QPointF(0,0) QPointF(0,0) QRectF(109.5,119.5 31x41)
Run Code Online (Sandbox Code Playgroud)
可能的出路:
setTransform。变换矩阵的变化被standards跟踪QGraphicsitem,并且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);
}
};
Run Code Online (Sandbox Code Playgroud)
您还应该跟踪项目转换和移动QGraphicsItem::itemChange。
| 归档时间: |
|
| 查看次数: |
3321 次 |
| 最近记录: |