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

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

View File

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

View File

@ -138,6 +138,31 @@ GraphicsItemGroup* DesignerScene::createGroup()
if(item && item->getType()==T_group)
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();
group->addItems(listItem);

View File

@ -81,6 +81,17 @@ void GraphicsBaseItem::rotateOperationCopy(const double& 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)
{
if (change == QGraphicsItem::ItemSelectedHasChanged)

View File

@ -56,12 +56,12 @@ void GraphicsItemGroup::paint(QPainter* painter, const QStyleOptionGraphicsItem*
painter->drawRect(m_boundingRect_selected);
//绘制变换原点
QPointF originPoint = transformOriginPoint();
/*QPointF originPoint = transformOriginPoint();
//qDebug() << "originPoint:" << originPoint << " boundingRect:" << m_boundingRect;
painter->setBrush(Qt::red);
painter->drawEllipse(QPointF(0,0), 4, 4);
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);
}
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()
{
if (!parentItem())
@ -121,8 +151,8 @@ void GraphicsItemGroup::updateCoordinate() //当执行了resie和editShape函数
//调用该组内所有item(过滤handle)相关函数
foreach (QGraphicsItem *item, childItems())
{
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem *>(item);
if (baseItem && !qgraphicsitem_cast<ItemControlHandle *>(baseItem))
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem*>(item);
if (baseItem && !qgraphicsitem_cast<ItemControlHandle*>(baseItem))
{
baseItem->updateCoordinate();
}
@ -161,8 +191,8 @@ void GraphicsItemGroup::resize(int nHandle,double dSX, double dSY, const QPointF
//调用该组内所有item(过滤handle)相关函数
foreach (QGraphicsItem *item, childItems())
{
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem *>(item);
if (baseItem && !qgraphicsitem_cast<ItemControlHandle *>(baseItem))
GraphicsBaseItem *baseItem = qgraphicsitem_cast<GraphicsBaseItem*>(item);
if (baseItem && !qgraphicsitem_cast<ItemControlHandle*>(baseItem))
{
baseItem->resize(nHandle, dSX, dSY, baseItem->mapFromParent(basePoint));
}
@ -196,7 +226,30 @@ void GraphicsItemGroup::removeOperationCopy()
if(this->pos() != m_pOperationCopy->pos())
this->setPos(m_pOperationCopy->pos()); //本体移动到副本的位置
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);
delete m_pOperationCopy;

View File

@ -129,6 +129,13 @@ void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene
{
//划分为四组区间范围,分别水平组、垂直组、一三象限倾斜组、二四象限倾斜组,每组由两个对称区间构成
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;
switch (nHandle)

View File

@ -43,7 +43,7 @@ void RotationSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerS
rotationAngle += 360;
item->rotateOperationCopy(rotationAngle);
//qDebug() << " rotationAngle:" << rotationAngle;
//qDebug() << "rotationAngle: " << rotationAngle;
}
}
}