QGraphicsItem调用update函数的原理

问题1:假如在一个场景中有多个QGraphicsItem(例如a,b,c,d,e,f,g),调用其中一个QGraphicsItem (例如a)中的 update()函数。 是不是 执行了a 所在的 QGraphicsView 中的paint函数 和 所有界面能显示出来的QGraphicsItem(例如 a,b,c,d能看到 e,f,g不能看到) 中的paint()函数。

问题2:当多个QGraphicsItem 在很短的时间内调用update函数 (估计是毫秒级别的时间段内)是不是场景只执行了一次重绘操作。



1、查了一下,Qt5中QGraphicsView没有paint成员函数;看源码,应该是需要update的时候将item所在的矩形标记为脏,然后通过Scene - View - Viewport逐次调用update( rect )。
2、如果是directUpdate,那么在QGraphicsScene中可以立即调用QGraphicsView的相关函数进行重绘,否则会在所有item循环update后进行重绘。

有点记不住了,可能会有点小偏差
1 item中的paint(Qpainter* painter, xxxx,xxxx);
这个painter是view中构建的
2 你调用item的update.
按照grphics system的设计思想,应该是所有可见这个item view需要重绘。
3 如果update是通过事件发送的话,不像是glwidget那种直接调用paint。
那么,Qt会帮你合并这个update事件。

### 回答1: 在使用Qt的QGraphicsItem移动对象时,可以通过吸附到网格来控制移动的位置。实现网格吸附的方法如下: 1. 定义网格大小:首先需要定义网格的大小,可以是固定大小或者根据场景的尺寸动态计算,以确保吸附网格适应场景的大小。 2. 重写itemChange()函数:在QGraphicsItem的派生类中重写itemChange()函数。该函数在对象的一些属性变化时被调用,可以捕捉到对象的移动操作。 3. 实现网格吸附逻辑:在重写的itemChange()函数中,获取移动的位置信息,并将其对齐到网格上合适的位置。可以使用Qt的round()函数将位置舍入到最接近的网格点。例如,如果网格大小为10像素,可以这样计算吸附的位置:roundedPos = round(pos / gridSize) * gridSize。 4. 更新位置:根据计算得到的吸附位置,更新对象的位置。可以使用QGraphicsItem的setPos()函数将对象移动到新位置。 下面是一个简化的示例代码,演示了如何实现QGraphicsItem的吸附网格功能: ```cpp class MyGraphicsItem : public QGraphicsItem { public: MyGraphicsItem() { // 初始化网格大小 gridSize = 10; } QRectF boundingRect() const override { // 返回对象的外包矩形 } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { // 绘制对象的外观 } QVariant itemChange(GraphicsItemChange change, const QVariant &value) override { if (change == ItemPositionChange && scene()) { // 获取移动的位置 QPointF newPos = value.toPointF(); // 吸附到网格 qreal roundedX = round(newPos.x() / gridSize) * gridSize; qreal roundedY = round(newPos.y() / gridSize) * gridSize; newPos.setX(roundedX); newPos.setY(roundedY); // 更新位置 return newPos; } return QGraphicsItem::itemChange(change, value); } private: qreal gridSize; }; ``` 使用上述代码可以实现QGraphicsItem对象在移动时自动吸附到网格位置,使得移动更加精确和有序。根据实际需求,可以调整网格大小和吸附逻辑来满足不同的需求。 ### 回答2: QGraphicsItem是Qt框架提供的类,用于在图形场景中绘制和操作2D图形元素。要实现QGraphicsItem在移动时吸附到网格上,可以按以下步骤进行。 1. 创建自定义的QGraphicsItem子类,例如MyGraphicsItem,重写其mouseMoveEvent函数。 2. 在mouseMoveEvent函数中,获取鼠标当前位置,并根据吸附网格的尺寸和间隔,计算出最近的网格交叉点的坐标。 3. 将MyGraphicsItem的位置设置为计算出的网格交叉点坐标,并调用update函数以更新图形场景中该图形项的显示。 以下是一个简单的示例代码: ```cpp class MyGraphicsItem : public QGraphicsItem { public: MyGraphicsItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent) { setFlags(ItemIsMovable); } QRectF boundingRect() const override { return QRectF(-10, -10, 20, 20); // 定义图形项的边界矩形 } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { painter->drawRect(boundingRect()); // 绘制图形项的内容 } void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override { QPointF newPos = event->scenePos(); // 获取鼠标当前位置 int gridSize = 50; // 网格间距 qreal x = round(newPos.x() / gridSize) * gridSize; // 计算最近的网格交叉点的x坐标 qreal y = round(newPos.y() / gridSize) * gridSize; // 计算最近的网格交叉点的y坐标 setPos(x, y); // 将位置设置为计算出的网格交叉点坐标 update(); // 更新图形场景中图形项的显示 } }; ``` 在使用MyGraphicsItem时,将其添加到QGraphicsScene中,并将QGraphicsScene设置给QGraphicsView显示。然后,当鼠标拖动MyGraphicsItem时,它将在移动过程中吸附到网格上。 ### 回答3: QGraphicsItem 是 Qt 提供的一个图形项类,用于在 QGraphicsScene 中显示和操作图形对象。要实现 QGraphicsItem 的移动吸附网格,可以通过重写 QGraphicsItem 的鼠标事件来实现。 首先,在 QGraphicsItem 的子类中,重写鼠标按下、鼠标移动和鼠标释放事件。在鼠标按下事件里,记录下鼠标点击的初始位置和图形项的初始位置。在鼠标移动事件里,计算出鼠标移动的偏移量,然后根据偏移量来更新图形项的位置。在鼠标释放事件里,将鼠标位置与网格的尺寸对齐,并更新图形项的位置。 在计算偏移量时,可以将鼠标位置和初始位置的差值与网格的大小取余,得到对齐到网格的偏移量。再将图形项的初始位置加上这个偏移量,就可以获得对齐到网格的新位置。在更新图形项的位置时,使用 QGraphicsItem 的 setPos 函数来设置新的位置。 这样,当鼠标拖动图形项时,会自动吸附到网格的位置上。通过调整网格的大小,可以控制吸附的精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值