优化打组操作,消除多层组群结构,便于管理和相关变换计算

This commit is contained in:
duanshengchao 2024-09-03 15:42:19 +08:00
parent da6b9d023b
commit 0f6de6317e
7 changed files with 114 additions and 10 deletions

View File

@ -28,6 +28,7 @@ public:
m_brush = QBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8)); m_brush = QBrush(QColor(rand() % 32 * 8, rand() % 32 * 8, rand() % 32 * 8));
m_dWidth = m_dHeight = 0; m_dWidth = m_dHeight = 0;
m_pOperationCopy = nullptr; m_pOperationCopy = nullptr;
m_dSyncRotationByParent = 0.0;
} }
virtual ~AbstractShapeType() virtual ~AbstractShapeType()
@ -256,6 +257,9 @@ public:
return path; return path;
} }
virtual void syncRotationDataFromParent(const double&) {}
virtual double getSyncRotationDataFromParent() {return m_dSyncRotationByParent;}
protected: protected:
ShapeType m_type; ShapeType m_type;
QPen m_pen; QPen m_pen;
@ -265,8 +269,10 @@ protected:
QRectF m_boundingRect; QRectF m_boundingRect;
QRectF m_boundingRect_selected; //选中矩形框 QRectF m_boundingRect_selected; //选中矩形框
double m_dSyncRotationByParent; //父项(被加入到某一组)的旋转数据,因为加入某一组后,对该组进行旋转,自身的旋转数据不会同步更新
QGraphicsPathItem* m_pOperationCopy; //图元移动和旋转时的操作副本 QGraphicsPathItem* m_pOperationCopy; //图元移动和旋转时的操作副本
QPointF m_movingIniPos; //移动副本开始移动初始点 QPointF m_movingIniPos; //移动副本开始移动初始
QVector<ItemControlHandle*> m_vecHanle; QVector<ItemControlHandle*> m_vecHanle;
}; };
@ -285,6 +291,7 @@ public:
virtual void removeOperationCopy(); virtual void removeOperationCopy();
virtual void moveOperationCopy(const QPointF&); virtual void moveOperationCopy(const QPointF&);
virtual void rotateOperationCopy(const double&); virtual void rotateOperationCopy(const double&);
virtual void syncRotationDataFromParent(const double&);
//多边形、线段等点选创建的对象需要的函数 //多边形、线段等点选创建的对象需要的函数
virtual void addPoint(const QPointF&) {} virtual void addPoint(const QPointF&) {}
virtual bool endDrawing() { return true; } virtual bool endDrawing() { return true; }

View File

@ -27,6 +27,7 @@ protected:
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*); virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*); virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&); virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void syncRotationDataFromParent(const double&);
private: private:
QRectF m_lastBoudingRect; //记录上一时刻的boundingRect QRectF m_lastBoudingRect; //记录上一时刻的boundingRect

View File

@ -138,6 +138,31 @@ GraphicsItemGroup* DesignerScene::createGroup()
if(item && item->getType()==T_group) if(item && item->getType()==T_group)
return nullptr; return nullptr;
} }
else //如果选择的有组群则拆散该组群并和其它单独的itme组合成新组群防止多层组群出现方便管理和计算
{
for(int n=0; n<listItem.count(); n++)
{
AbstractShape* shape = qgraphicsitem_cast<AbstractShape*>(listItem[n]);
if(shape && shape->getType()==T_group)
{
GraphicsItemGroup* group = qgraphicsitem_cast<GraphicsItemGroup*>(listItem[n]);
QList<QGraphicsItem*> childItems = group->childItems();
foreach (QGraphicsItem* child, childItems)
{
if(qgraphicsitem_cast<ItemControlHandle*>(child))
continue;
group->removeFromGroup(child);
listItem.push_back(child);
}
listItem.takeAt(n);
removeItem(group);
delete group;
n--;
}
}
}
GraphicsItemGroup* group = new GraphicsItemGroup(); GraphicsItemGroup* group = new GraphicsItemGroup();
group->addItems(listItem); group->addItems(listItem);

View File

@ -81,6 +81,17 @@ void GraphicsBaseItem::rotateOperationCopy(const double& dAngle)
m_pOperationCopy->setRotation(dAngle); m_pOperationCopy->setRotation(dAngle);
} }
void GraphicsBaseItem::syncRotationDataFromParent(const double& data)
{
//m_dSyncRotationByParent = rotation() + data;
m_dSyncRotationByParent += data;
//让角度保持在正负180的区间也就是上下两个半圈这样易于象限判断
if (m_dSyncRotationByParent > 180)
m_dSyncRotationByParent -= 360;
if (m_dSyncRotationByParent < -180)
m_dSyncRotationByParent += 360;
}
QVariant GraphicsBaseItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) QVariant GraphicsBaseItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
{ {
if (change == QGraphicsItem::ItemSelectedHasChanged) if (change == QGraphicsItem::ItemSelectedHasChanged)

View File

@ -56,12 +56,12 @@ void GraphicsItemGroup::paint(QPainter* painter, const QStyleOptionGraphicsItem*
painter->drawRect(m_boundingRect_selected); painter->drawRect(m_boundingRect_selected);
//绘制变换原点 //绘制变换原点
QPointF originPoint = transformOriginPoint(); /*QPointF originPoint = transformOriginPoint();
//qDebug() << "originPoint:" << originPoint << " boundingRect:" << m_boundingRect; //qDebug() << "originPoint:" << originPoint << " boundingRect:" << m_boundingRect;
painter->setBrush(Qt::red); painter->setBrush(Qt::red);
painter->drawEllipse(QPointF(0,0), 4, 4); painter->drawEllipse(QPointF(0,0), 4, 4);
painter->setBrush(Qt::blue); painter->setBrush(Qt::blue);
painter->drawEllipse(originPoint, 4, 4); painter->drawEllipse(originPoint, 4, 4);*/
} }
} }
@ -86,6 +86,36 @@ QVariant GraphicsItemGroup::itemChange(QGraphicsItem::GraphicsItemChange change,
return QGraphicsItemGroup::itemChange(change, value); return QGraphicsItemGroup::itemChange(change, value);
} }
void GraphicsItemGroup::syncRotationDataFromParent(const double& data)
{
/*m_dSyncRotationByParent += data;
//让角度保持在正负180的区间也就是上下两个半圈这样易于象限判断
if (m_dSyncRotationByParent > 180)
m_dSyncRotationByParent -= 360;
if (m_dSyncRotationByParent < -180)
m_dSyncRotationByParent += 360;
//同步给子项
foreach (QGraphicsItem* item, childItems())
{
if(qgraphicsitem_cast<ItemControlHandle*>(item))
continue;
AbstractShape* shape = qgraphicsitem_cast<AbstractShape*>(item);
if(shape && shape->getType()==T_group)
{
GraphicsItemGroup *group = qgraphicsitem_cast<GraphicsItemGroup *>(item);
if(group)
group->syncRotationDataFromParent(data);
}
else
{
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem*>(item);
if (baseItem)
baseItem->syncRotationDataFromParent(data);
}
}*/
}
void GraphicsItemGroup::updateCoordinate() //当执行了resie和editShape函数后boundingRect发生了变换需要将item的原点(以中心点为原点)校准至boundingRect.center() void GraphicsItemGroup::updateCoordinate() //当执行了resie和editShape函数后boundingRect发生了变换需要将item的原点(以中心点为原点)校准至boundingRect.center()
{ {
if (!parentItem()) if (!parentItem())
@ -196,7 +226,30 @@ void GraphicsItemGroup::removeOperationCopy()
if(this->pos() != m_pOperationCopy->pos()) if(this->pos() != m_pOperationCopy->pos())
this->setPos(m_pOperationCopy->pos()); //本体移动到副本的位置 this->setPos(m_pOperationCopy->pos()); //本体移动到副本的位置
if(this->rotation() != m_pOperationCopy->rotation()) if(this->rotation() != m_pOperationCopy->rotation())
this->setRotation(m_pOperationCopy->rotation()); //本体旋转至副本的角度 {
double dAngle = m_pOperationCopy->rotation();
this->setRotation(dAngle); //本体旋转至副本的角度
//子item的旋转数据并不会和所在组同步需要手动同步
foreach (QGraphicsItem* item, childItems())
{
if(qgraphicsitem_cast<ItemControlHandle*>(item))
continue;
// AbstractShape* shape = qgraphicsitem_cast<AbstractShape*>(item);
// if(shape && shape->getType()==T_group)
// {
// GraphicsItemGroup *group = qgraphicsitem_cast<GraphicsItemGroup *>(item);
// if(group)
// group->syncRotationDataFromParent(dAngle);
// }
// else
{
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem*>(item);
if (baseItem)
baseItem->syncRotationDataFromParent(dAngle);
}
}
}
scene->removeItem(m_pOperationCopy); scene->removeItem(m_pOperationCopy);
delete m_pOperationCopy; delete m_pOperationCopy;

View File

@ -129,6 +129,13 @@ void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene
{ {
//划分为四组区间范围,分别水平组、垂直组、一三象限倾斜组、二四象限倾斜组,每组由两个对称区间构成 //划分为四组区间范围,分别水平组、垂直组、一三象限倾斜组、二四象限倾斜组,每组由两个对称区间构成
double dRotation = item->rotation(); double dRotation = item->rotation();
dRotation += item->getSyncRotationDataFromParent();
//让角度保持在正负180的区间也就是上下两个半圈这样易于象限判断
if (dRotation > 180)
dRotation -= 360;
if (dRotation < -180)
dRotation += 360;
//qDebug() << "selfRotation:" << item->rotation() << " syncRotation:" << item->getSyncRotationDataFromParent() << " fininalRotatio:" << dRotation;
double dTileAngle = 15.0; double dTileAngle = 15.0;
switch (nHandle) switch (nHandle)