修复采用拖拽方式进行创建的item和缩放操作有轻微漂移的bug

This commit is contained in:
duanshengchao 2024-11-20 14:40:13 +08:00
parent 0f6de6317e
commit b234cdd3ca
8 changed files with 54 additions and 29 deletions

View File

@ -122,32 +122,40 @@ public:
virtual QPointF getSymmetricPointPos(int nHandle) //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
{
QPointF pt;
//编号从1开始因此下标需要-1
//handle的位置相对boundingRect会有一个向外的错位因此直接采用bounddingRect的相应位置会更精准
switch (nHandle)
{
case H_leftTop:
pt = m_vecHanle.at(H_rightBottom - 1)->pos();
//pt = m_vecHanle.at(H_rightBottom - 1)->pos();
pt = m_boundingRect.bottomRight();
break;
case H_top:
pt = m_vecHanle.at(H_bottom - 1)->pos();
//pt = m_vecHanle.at(H_bottom - 1)->pos();
pt = QPointF(m_boundingRect.width() * 0.5, m_boundingRect.bottom());
break;
case H_rightTop:
pt = m_vecHanle.at(H_leftBottom - 1)->pos();
//pt = m_vecHanle.at(H_leftBottom - 1)->pos();
pt = m_boundingRect.bottomLeft();
break;
case H_right:
pt = m_vecHanle.at(H_left - 1)->pos();
//pt = m_vecHanle.at(H_left - 1)->pos();
pt = QPointF(m_boundingRect.left(), m_boundingRect.height() * 0.5);
break;
case H_rightBottom:
pt = m_vecHanle.at(H_leftTop - 1)->pos();
//pt = m_vecHanle.at(H_leftTop - 1)->pos();
pt = m_boundingRect.topLeft();
break;
case H_bottom:
pt = m_vecHanle.at(H_top - 1)->pos();
//pt = m_vecHanle.at(H_top - 1)->pos();
pt = QPointF(m_boundingRect.width() * 0.5, m_boundingRect.top());
break;
case H_leftBottom:
pt = m_vecHanle.at(H_rightTop - 1)->pos();
//pt = m_vecHanle.at(H_rightTop - 1)->pos();
pt = m_boundingRect.topRight();
break;
case H_left:
pt = m_vecHanle.at(H_right - 1)->pos();
//pt = m_vecHanle.at(H_right - 1)->pos();
pt = QPointF(m_boundingRect.right(), m_boundingRect.height() * 0.5);
break;
default:
break;

View File

@ -20,7 +20,7 @@ public:
void rotateOperationCopy(const double&);
void addItems(const QList<QGraphicsItem*>&);
QList<QGraphicsItem*> getItems() {return m_listItem;}
//QList<QGraphicsItem*> getItems() {return m_listItem;}
protected:
virtual QPainterPath shape();
@ -30,8 +30,9 @@ protected:
virtual void syncRotationDataFromParent(const double&);
private:
QRectF m_lastBoudingRect; //记录上一时刻的boundingRect
QList<QGraphicsItem*> m_listItem;
QRectF m_lastBoudingRect; //记录上一时刻的boundingRect
QPainterPath m_painterPath;
//QList<QGraphicsItem*> m_listItem;
};
#endif

View File

@ -38,7 +38,7 @@ private:
CreatingMethod m_creatingMethod;
GraphicsItemType m_creatingItemType;
GraphicsBaseItem* m_pCreatingItem;
QPointF m_scalBasePoint;
//QPointF m_scalBasePoint;
};
#endif

View File

@ -183,6 +183,8 @@ void GraphicsItemGroup::resize(int nHandle,double dSX, double dSY, const QPointF
trans.translate(-basePoint.x(), -basePoint.y());
prepareGeometryChange();
//如果直接将变换应用到item(setTransform(trans)),相当于把坐标进行拉伸,会有明显的拉伸感,所以应用到图形点上效果更好
//setTransform(trans);
m_boundingRect = trans.mapRect(m_lastBoudingRect);
m_dWidth = m_boundingRect.width();
m_dHeight = m_boundingRect.height();
@ -194,7 +196,8 @@ void GraphicsItemGroup::resize(int nHandle,double dSX, double dSY, const QPointF
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem*>(item);
if (baseItem && !qgraphicsitem_cast<ItemControlHandle*>(baseItem))
{
baseItem->resize(nHandle, dSX, dSY, baseItem->mapFromParent(basePoint));
//qDebug() << "groupBounding: " << m_boundingRect << " itemBounding:" << baseItem->boundingRect();
baseItem->resize(nHandle, dSX, dSY, baseItem->mapFromParent(basePoint));
}
}
}
@ -278,7 +281,7 @@ void GraphicsItemGroup::addItems(const QList<QGraphicsItem*>& items)
{
item->setSelected(false);
addToGroup(item);
m_listItem.push_back(item);
//m_listItem.push_back(item);
}
updateCoordinate();

View File

@ -51,8 +51,8 @@ void GraphicPolygonItem::updateCoordinate() //当执行了resie和editShape函
prepareGeometryChange();
//更改图形绘制节点坐标,让图形中心和原点对齐
QPolygonF ptsOnScene = mapToScene(m_points); //所有操作都在scene坐标系下进行然后在还原至item坐标系否则会有跳转
for(int i=0; i<m_points.count(); i++)
ptsOnScene[i] += delta; //一定要在scene坐标系下执行操作不能直接m_points += delta;因为缩放以后item自身的内部坐标系也会同步缩放单位刻度和scene下的单位刻度不再一致,所以所有相关计算一定要在同一个坐标系下完成
for(int i=0; i<ptsOnScene.count(); i++)
ptsOnScene[i] += delta; //一定要在scene坐标系下执行操作不能直接m_points += delta;因为旋转以后item自身的内部坐标系和scene下的不再一致,所以所有相关计算一定要在同一个坐标系下完成
m_points = mapFromScene(ptsOnScene);
m_boundingRect = m_points.boundingRect();
//移动整体图形,消除节点坐标更后的绘制跳转

View File

@ -123,6 +123,7 @@ void GraphicsRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*
void GraphicsRectItem::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint)
{
//qDebug() << basePoint;
switch (nHandle)
{
case H_left:

View File

@ -68,7 +68,12 @@ CreateItemGoupCommand::CreateItemGoupCommand(GraphicsItemGroup* group, QGraphics
{
m_pGroup = group;
m_pGraphicsScene = scene;
m_listItem = group->getItems();
foreach (QGraphicsItem *item, group->childItems())
{
if(!qgraphicsitem_cast<ItemControlHandle*>(item))
m_listItem.push_back(item);
}
//m_listItem = group->getItems();
}
CreateItemGoupCommand::~CreateItemGoupCommand()
{
@ -108,7 +113,12 @@ DestroyItemGoupCommand::DestroyItemGoupCommand(GraphicsItemGroup* group, QGraphi
{
m_pGroup = group;
m_pGraphicsScene = scene;
m_listItem = group->getItems();
foreach (QGraphicsItem *item, group->childItems())
{
if(!qgraphicsitem_cast<ItemControlHandle*>(item))
m_listItem.push_back(item);
}
//m_listItem = group->getItems();
}
DestroyItemGoupCommand::~DestroyItemGoupCommand()
{
@ -120,8 +130,9 @@ void DestroyItemGoupCommand::undo()
item->setSelected(false);
m_pGroup->addToGroup(item);
}
m_pGroup->setSelected(true);
m_pGraphicsScene->addItem(m_pGroup);
m_pGroup->setSelected(true);
m_pGraphicsScene->update();
}
void DestroyItemGoupCommand::redo()

View File

@ -10,7 +10,7 @@ CreatingSelector::CreatingSelector(QObject *parent)
m_type = ST_cerating;
m_creatingMethod = CM_drag;
m_pCreatingItem = nullptr;
m_scalBasePoint = QPointF();
//m_scalBasePoint = QPointF();
}
CreatingSelector::~CreatingSelector()
{
@ -34,7 +34,7 @@ void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, Designer
case GIT_rect:
{
m_creatingMethod = CM_drag;
m_pCreatingItem = new GraphicsRectItem(QRect(1, 1, 1, 1));
m_pCreatingItem = new GraphicsRectItem(QRect(-2, -2, 4, 4));
}
break;
case GIT_roundRect:
@ -86,22 +86,23 @@ void CreatingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerS
if (m_pCreatingItem && m_creatingMethod == CM_drag)
{
if(m_scalBasePoint.isNull()) //基准点不能采用临时变量因为handle的坐标也在不断变化计算会出现问题
/*if(m_scalBasePoint.isNull()) //基准点不能采用临时变量因为handle的坐标也在不断变化计算会出现问题
{
m_scalBasePoint = m_pCreatingItem->getSymmetricPointPos(ms_nDragHandle);
m_scalBasePoint = m_pCreatingItem->getSymmetricPointPos(ms_nDragHandle); qDebug() << m_scalBasePoint;
if(m_scalBasePoint.x() == 0)
m_scalBasePoint.setX(1);
if(m_scalBasePoint.y() == 0)
m_scalBasePoint.setY(1);
}
}*/
QPointF scaleBasePoint = m_pCreatingItem->boundingRect().topLeft();
//计算缩放倍数
QPointF iniDelta = m_pCreatingItem->mapFromScene(ms_ptMouseDown) - m_scalBasePoint;
QPointF lastDelta = m_pCreatingItem->mapFromScene(ms_ptMouseLast) - m_scalBasePoint;
QPointF iniDelta = m_pCreatingItem->mapFromScene(ms_ptMouseDown) - scaleBasePoint;
QPointF lastDelta = m_pCreatingItem->mapFromScene(ms_ptMouseLast) - scaleBasePoint;
double sx = lastDelta.x() / iniDelta.x();
double sy = lastDelta.y() / iniDelta.y();
m_pCreatingItem->resize(ms_nDragHandle, sx, sy, m_scalBasePoint);
m_pCreatingItem->resize(ms_nDragHandle, sx, sy, scaleBasePoint);
}
else if (m_pCreatingItem && m_creatingMethod == CM_click)
{
@ -130,7 +131,7 @@ void CreatingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, Design
ms_nDragHandle = H_none;
m_pCreatingItem = nullptr;
m_scalBasePoint = QPointF();
//m_scalBasePoint = QPointF();
setCursor(scene, Qt::ArrowCursor);
emit setWorkingSelector(ST_base);
}