实现矩形和圆角矩形的添加

This commit is contained in:
duanshengchao 2024-08-09 16:00:52 +08:00
parent 14131ce209
commit 02f3f5bebb
34 changed files with 1632 additions and 34 deletions

30
include/designerScene.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef DESIGNER_SCENE_H
#define DESIGNER_SCENE_H
#include <QGraphicsScene>
class DesignerScene : public QGraphicsScene
{
Q_OBJECT
public:
explicit DesignerScene(QObject *parent = 0);
virtual ~DesignerScene();
void setGridVisible(bool);
void setView(QGraphicsView* view) { m_pView = view; }
QGraphicsView *getView() { return m_pView; }
void callParentEvent(QGraphicsSceneMouseEvent*);
protected:
void drawBackground(QPainter*, const QRectF&) override;
void mousePressEvent(QGraphicsSceneMouseEvent*) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
private:
bool m_bGridVisible;
QGraphicsView* m_pView;
};
#endif

18
include/designerView.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef DESIGNER_VIEW_H
#define DESIGNER_VIEW_H
#include <QGraphicsView>
class DesignerView : public QGraphicsView
{
Q_OBJECT
public:
explicit DesignerView(QWidget *parent = 0);
virtual ~DesignerView();
private:
void initialize();
};
#endif

32
include/drawingPanel.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef DRAWINGPANEL_H
#define DRAWINGPANEL_H
#include <QWidget>
#include "global.h"
QT_BEGIN_NAMESPACE
namespace Ui { class drawingPanel; }
QT_END_NAMESPACE
class DesignerView;
class DesignerScene;
class DrawingPanel : public QWidget
{
Q_OBJECT
public:
DrawingPanel(QWidget *parent = nullptr);
~DrawingPanel();
public slots:
void onSignal_addGraphicsItem(GraphicsItemType&);
private:
Ui::drawingPanel *ui;
DesignerView* m_pGraphicsView;
DesignerScene* m_pGraphicsScene;
};
#endif

19
include/global.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef GLOBAL_H
#define GLOBAL_H
#include <QGraphicsItem>
const double g_dGriaphicsScene_Width = 5000;
const double g_dGriaphicsScene_Height = 5000;
enum GraphicsItemType
{
GIT_base = QGraphicsItem::UserType + 1,
GIT_line = QGraphicsItem::UserType + 2,
GIT_rect = QGraphicsItem::UserType + 3,
GIT_roundRect = QGraphicsItem::UserType + 4,
GIT_ellipse = QGraphicsItem::UserType + 5,
GIT_polygon = QGraphicsItem::UserType + 6
};
#endif

View File

@ -0,0 +1,30 @@
#ifndef GRAPHICELEMENTSPANEL_H
#define GRAPHICELEMENTSPANEL_H
#include <QWidget>
#include "global.h"
QT_BEGIN_NAMESPACE
namespace Ui { class graphicElementsPanel; }
QT_END_NAMESPACE
class GraphicElementsPanel : public QWidget
{
Q_OBJECT
public:
GraphicElementsPanel(QWidget *parent = nullptr);
~GraphicElementsPanel();
signals:
void addGraphicsItem(GraphicsItemType&);
public slots:
void onBtnClicked_GraphicsItem();
private:
Ui::graphicElementsPanel *ui;
};
#endif

View File

@ -0,0 +1,60 @@
#ifndef GRAPHICSBASEITEM_H
#define GRAPHICSBASEITEM_H
#include "itemControlHandle.h"
#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QPen>
class GraphicsBaseItem : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
GraphicsBaseItem(QGraphicsItem *parent);
virtual ~GraphicsBaseItem();
public:
QPen pen() { return m_pen; }
void setPen(const QPen &pen) { m_pen = pen; }
QColor penColor() { return m_pen.color(); }
void setPenColor(const QColor &color) { m_pen.setColor(color); }
QBrush brush() { return m_brush; }
void setBrush(const QBrush &brush) { m_brush = brush; }
QColor brushColor() { return m_brush.color(); }
void setBrushColor(const QColor &color) { m_brush.setColor(color); }
double width() { return m_dWidth; }
void setWidth(double);
double height() { return m_dHeight; }
void setHeight(double);
virtual QRectF boundingRect() const { return m_boundingRect; }
virtual void updateHandles();
virtual void resize(int,double, double, const QPointF&) {}
virtual void updateCoordinate() {}
virtual void move(const QPointF& point) { Q_UNUSED(point); }
virtual QVariant itemChange(QGraphicsItem::GraphicsItemChange, const QVariant&);
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent*);
//handle相关
virtual void setHandleVisible(bool);
virtual QPointF getSymmetricPointPos(int); //获取对称点的坐标位置,缩放的时候需要以对称点为锚点
protected:
QPen m_pen;
QBrush m_brush;
double m_dWidth;
double m_dHeight;
QRectF m_boundingRect;
QVector<ItemControlHandle*> m_vecHanle;
};
#endif

View File

@ -0,0 +1,29 @@
#ifndef GRAPHICSRECTITEM_H
#define GRAPHICSRECTITEM_H
#include "graphicsBaseItem.h"
class GraphicsRectItem : public GraphicsBaseItem
{
public:
GraphicsRectItem(const QRect &rect, bool isRound = false, QGraphicsItem *parent = 0);
virtual ~GraphicsRectItem();
void resize(int,double, double, const QPointF&);
void updateCoordinate();
void move(const QPointF&);
protected:
virtual QPainterPath shape();
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*);
private:
virtual void updateHandles();
QRectF m_lastBoudingRect; //记录上一时刻的boundingRect
bool m_bIsRound; //是否为圆角矩形
double m_dRatioX;
double m_dRatioY;
};
#endif

View File

@ -0,0 +1,55 @@
#ifndef ITEMCONTROLHANDLE_H
#define ITEMCONTROLHANDLE_H
#include <QGraphicsRectItem>
enum HandleType
{
T_resize, //调整大小
T_editShape //编辑形状
};
enum HandleTag
{
H_none = 0,
H_leftTop,
H_top,
H_rightTop,
H_right,
H_rightBottom,
H_bottom,
H_leftBottom,
H_left, //8
H_edit
};
class ItemControlHandle : public QObject,public QGraphicsRectItem
{
Q_OBJECT
public:
ItemControlHandle(QGraphicsItem *parent);
virtual ~ItemControlHandle();
public:
void setType(HandleType ht) { m_type = ht; }
HandleType getType() { return m_type; }
void setTag(int ht) { m_tag = ht; }
int getTag() { return m_tag; }
void move(double, double);
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override;
virtual void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
private:
HandleType m_type;
int m_tag;
};
#endif

View File

@ -13,6 +13,9 @@ QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class DrawingPanel;
class GraphicElementsPanel;
class CMainWindow : public QMainWindow
{
Q_OBJECT
@ -35,6 +38,9 @@ private:
ads::CDockAreaWidget* StatusDockArea;
ads::CDockWidget* TimelineDockWidget;
DrawingPanel* m_pDrawingPanel;
GraphicElementsPanel* m_pGraphicElementsPanel;
void createPerspectiveUi();
private slots:

View File

@ -0,0 +1,67 @@
/**
*\file baseSelector.h
*
*\brief selector是用来实现图元具体操作的行为类
*
*\author dsc
*/
#ifndef BASESELECTOR_H
#define BASESELECTOR_H
#include <QObject>
#include "designerScene.h"
enum SelectorType
{
ST_base = 0, //基本
ST_cerating, //创建
ST_editing, //顶点编辑
ST_scaling, //缩放
ST_rotating, //旋转
};
enum OperationMode
{
OM_none = 0,
OM_move, //移动
OM_create, //创建
OM_edit, //顶点编辑
OM_scale, //缩放
OM_rotate, //旋转
};
class BaseSelector : public QObject
{
Q_OBJECT
public:
explicit BaseSelector(QObject *parent = 0);
virtual ~BaseSelector();
public:
virtual void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
SelectorType getSelectorType() { return m_type; }
//void setOperationMode(OperationMode m) { m_opMode = m; }
OperationMode getOperationMode() { return ms_opMode; }
void setCursor(DesignerScene*, const QCursor&);
signals:
void setWorkingSelector(SelectorType);
protected:
//静态变量,用于不同类型对象间的成员共享
static OperationMode ms_opMode;
static QPointF ms_ptMouseDown;
static QPointF ms_ptMouseLast;
static int ms_nDragHandle; //当前抓取的控制点
SelectorType m_type;
bool m_bHoverOnHandel; //鼠标是否悬停在handel
};
#endif

View File

@ -0,0 +1,36 @@
/**
*\file creatingSelector.h
*
*\brief selector
*
*\author dsc
*/
#ifndef CREATINGSELECTOR_H
#define CREATINGSELECTOR_H
#include "baseSelector.h"
#include "global.h"
class GraphicsBaseItem;
class CreatingSelector : public BaseSelector
{
Q_OBJECT
public:
explicit CreatingSelector(QObject *parent = 0);
virtual ~CreatingSelector();
public:
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void setCreatingItem(GraphicsItemType& type) { m_creatingType=type; }
private:
GraphicsItemType m_creatingType;
GraphicsBaseItem* m_pCreatingItem;
};
#endif

View File

@ -0,0 +1,29 @@
/**
*\file selectionSelector.h
*
*\brief selectorselector
*
*\author dsc
*/
#ifndef SELECTIONSELECTOR_H
#define SELECTIONSELECTOR_H
#include "baseSelector.h"
class SelectionSelector : public BaseSelector
{
Q_OBJECT
public:
explicit SelectionSelector(QObject *parent = 0);
virtual ~SelectionSelector();
public:
void mousePressEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*, DesignerScene*);
};
#endif

View File

@ -0,0 +1,60 @@
/**
*\file selectorManager.h
*
*\brief selector管理类,
* selector只需实例一个对象
*\author dsc
*/
#ifndef SELECTORMANAGER_H
#define SELECTORMANAGER_H
#include <QObject>
#include "baseSelector.h"
#include "global.h"
class SelectorManager : public QObject
{
Q_OBJECT
public:
SelectorManager(QObject *parent = 0);
~SelectorManager();
public:
static SelectorManager* getInstance();
void setWorkingSelector(SelectorType s) { m_curSelector=s; }
BaseSelector* getWorkingSelector(); //根据操作方式获取selector
void setDrawGraphicsItem(GraphicsItemType);
public slots:
void onSignal_setWorkingSelector(SelectorType);
private:
/*
*/
class CGarbo //它的唯一函数就是在析构函数中删除vsBaseData的实例
{
public:
CGarbo() {};
~CGarbo()
{
if (m_pInstance != nullptr)
{
//qDebug()<<"goodbye CGarbo";
delete m_pInstance;
m_pInstance = nullptr;
}
}
};
private:
static SelectorManager* m_pInstance;
SelectorType m_curSelector;
QVector<BaseSelector*> m_vecSelectors;
};
#endif

View File

@ -1,8 +1,5 @@
<RCC>
<qresource prefix="/">
<file>images/background1.png</file>
<file>images/background2.png</file>
<file>images/background3.png</file>
<file>images/background4.png</file>
</qresource>
<qresource prefix="/">
<file>images/checkerboard.png</file>
</qresource>
</RCC>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

101
source/designerScene.cpp Normal file
View File

@ -0,0 +1,101 @@
#include "designerScene.h"
#include "util/selectorManager.h"
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
DesignerScene::DesignerScene(QObject *parent)
: QGraphicsScene(parent)
{
m_bGridVisible = true;
m_pView = nullptr;
}
DesignerScene::~DesignerScene()
{
}
void DesignerScene::drawBackground(QPainter* painter, const QRectF& rect)
{
QGraphicsScene::drawBackground(painter, rect);
painter->fillRect(sceneRect(), Qt::white);
if(!m_bGridVisible)
return;
QRectF sceneRect = this->sceneRect();
QPen pen;
pen.setBrush(Qt::darkCyan);//藏青色
pen.setStyle(Qt::DashLine);
pen.setWidthF(0.2);
painter->setPen(pen);
int nGridSpace = 20; //暂时写死
//竖线
for(int nX = sceneRect.left(); nX < sceneRect.right(); nX += nGridSpace)
painter->drawLine(nX,sceneRect.top(),nX,sceneRect.bottom());
//横线
for(int nY = sceneRect.top(); nY < sceneRect.bottom(); nY += nGridSpace)
painter->drawLine(sceneRect.left(),nY,sceneRect.right(),nY);
//补齐最后两条
painter->drawLine(sceneRect.right(), sceneRect.top(), sceneRect.right(), sceneRect.bottom());
painter->drawLine(sceneRect.left(), sceneRect.bottom(), sceneRect.right(), sceneRect.bottom());
}
void DesignerScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
if(SelectorManager::getInstance())
{
SelectorManager::getInstance()->getWorkingSelector()->mousePressEvent(mouseEvent, this);
update();
}
else
QGraphicsScene::mousePressEvent(mouseEvent);
}
void DesignerScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
if(SelectorManager::getInstance())
{
SelectorManager::getInstance()->getWorkingSelector()->mouseMoveEvent(mouseEvent, this);
update();
}
else
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void DesignerScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
if(SelectorManager::getInstance())
{
SelectorManager::getInstance()->getWorkingSelector()->mouseReleaseEvent(mouseEvent, this);
update();
}
else
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
void DesignerScene::setGridVisible(bool bVisible)
{
m_bGridVisible = bVisible;
update();
}
void DesignerScene::callParentEvent(QGraphicsSceneMouseEvent* mouseEvent)
{
//调用QGraphicsScene的函数会直接触发一些操作比如取消item的selected状态从而触发item的一些函数itemChange,然后在item的相应函数中书写执行一些操作
switch (mouseEvent->type())
{
case QEvent::GraphicsSceneMousePress:
QGraphicsScene::mousePressEvent(mouseEvent);
break;
case QEvent::GraphicsSceneMouseMove:
QGraphicsScene::mouseMoveEvent(mouseEvent);
break;
case QEvent::GraphicsSceneMouseRelease:
QGraphicsScene::mouseReleaseEvent(mouseEvent);
break;
default:
break;
}
}

28
source/designerView.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "designerView.h"
DesignerView::DesignerView(QWidget *parent)
: QGraphicsView(parent)
{
initialize();
}
DesignerView::~DesignerView()
{
}
void DesignerView::initialize()
{
//去掉QGraphicsView自带滚动条
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
//设置背景
setStyleSheet("background-image: url(:/images/checkerboard.png);\
padding: 0px; \
border: 0px;");
//打开反锯齿
setRenderHint(QPainter::Antialiasing);
setMouseTracking(true);
//setDragMode(QGraphicsView::RubberBandDrag); //将控制交给selector
centerOn(0, 0);
}

38
source/drawingPanel.cpp Normal file
View File

@ -0,0 +1,38 @@
#include "drawingPanel.h"
#include "ui_drawingPanel.h"
#include "designerView.h"
#include "designerScene.h"
#include "util/selectorManager.h"
DrawingPanel::DrawingPanel(QWidget *parent)
: QWidget(parent)
, ui(new Ui::drawingPanel)
{
ui->setupUi(this);
m_pGraphicsScene = new DesignerScene(this);
//设置场景大小.前两个参数为scene的坐标远点设置到view的中心点后无论view如何缩放secne的坐标原点都不会动方便后续的位置计算
m_pGraphicsScene->setSceneRect(-g_dGriaphicsScene_Width / 2, -g_dGriaphicsScene_Height / 2, g_dGriaphicsScene_Width, g_dGriaphicsScene_Height);
m_pGraphicsScene->setGridVisible(true);
m_pGraphicsView = new DesignerView(this);
m_pGraphicsView->setScene(m_pGraphicsScene);
m_pGraphicsScene->setView(m_pGraphicsView);
ui->mainLayout->addWidget(m_pGraphicsView);
}
DrawingPanel::~DrawingPanel()
{
delete ui;
}
void DrawingPanel::onSignal_addGraphicsItem(GraphicsItemType& itemType)
{
if(SelectorManager::getInstance())
{
SelectorManager::getInstance()->setWorkingSelector(ST_cerating);
SelectorManager::getInstance()->setDrawGraphicsItem(itemType);
}
}

View File

@ -0,0 +1,26 @@
#include "graphicElementsPanel.h"
#include "ui_graphicElementsPanel.h"
GraphicElementsPanel::GraphicElementsPanel(QWidget *parent)
: QWidget(parent)
, ui(new Ui::graphicElementsPanel)
{
ui->setupUi(this);
ui->pushBtn_rect->setProperty("shap",GIT_rect);
connect(ui->pushBtn_rect, SIGNAL(clicked()), this, SLOT(onBtnClicked_GraphicsItem()));
ui->pushBtn_roundRect->setProperty("shap",GIT_roundRect);
connect(ui->pushBtn_roundRect, SIGNAL(clicked()), this, SLOT(onBtnClicked_GraphicsItem()));
}
GraphicElementsPanel::~GraphicElementsPanel()
{
delete ui;
}
void GraphicElementsPanel::onBtnClicked_GraphicsItem()
{
QObject* pObject = QObject::sender();
GraphicsItemType itetType = (GraphicsItemType)pObject->property("shap").toInt();
emit addGraphicsItem(itetType);
}

View File

@ -0,0 +1,150 @@
#include "graphicsItem/graphicsBaseItem.h"
GraphicsBaseItem::GraphicsBaseItem(QGraphicsItem *parent)
:QGraphicsItem(parent)
{
//初始化缩放操作用的handle
m_vecHanle.reserve(H_left);
for(int i = H_leftTop; i <= H_left; i++)
{
ItemControlHandle* pHandle = new ItemControlHandle(this);
pHandle->setType(T_resize);
pHandle->setTag(i);
m_vecHanle.push_back(pHandle);
}
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
setAcceptHoverEvents(true);
}
GraphicsBaseItem::~GraphicsBaseItem()
{
for (size_t i = 0; i < m_vecHanle.size(); i++)
{
ItemControlHandle* pHandle = m_vecHanle[i];
if (pHandle)
{
delete pHandle;
pHandle = nullptr;
}
}
}
void GraphicsBaseItem::setWidth(double width)
{
m_dWidth = width;
updateCoordinate();
}
void GraphicsBaseItem::setHeight(double height)
{
m_dHeight = height;
updateCoordinate();
}
QVariant GraphicsBaseItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value)
{
if (change == QGraphicsItem::ItemSelectedHasChanged)
{
QGraphicsItemGroup *group = dynamic_cast<QGraphicsItemGroup *>(parentItem());
if(!group)
setHandleVisible(value.toBool());
else //在某一组群中,由组群展示是否选中,自身不做展示
{
setSelected(false);
return QVariant::fromValue<bool>(false);
}
}
return QGraphicsItem::itemChange(change, value);
}
void GraphicsBaseItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event)
{
Q_UNUSED(event);
}
void GraphicsBaseItem::setHandleVisible(bool visible)
{
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
if(visible)
(*it)->show();
else
(*it)->hide();
}
}
QPointF GraphicsBaseItem::getSymmetricPointPos(int nHandle)
{
QPointF pt;
//编号从1开始因此下标需要-1
switch (nHandle)
{
case H_leftTop:
pt = m_vecHanle.at(H_rightBottom - 1)->pos();
break;
case H_top:
pt = m_vecHanle.at(H_bottom - 1)->pos();
break;
case H_rightTop:
pt = m_vecHanle.at(H_leftBottom - 1)->pos();
break;
case H_right:
pt = m_vecHanle.at(H_left - 1)->pos();
break;
case H_rightBottom:
pt = m_vecHanle.at(H_leftTop - 1)->pos();
break;
case H_bottom:
pt = m_vecHanle.at(H_top - 1)->pos();
break;
case H_leftBottom:
pt = m_vecHanle.at(H_rightTop - 1)->pos();
break;
case H_left:
pt = m_vecHanle.at(H_right - 1)->pos();
break;
default:
break;
}
return pt;
}
void GraphicsBaseItem::updateHandles()
{
const QRectF& boundRect = this->boundingRect();
for(auto it = m_vecHanle.begin(); it != m_vecHanle.end(); it++)
{
switch ((*it)->getTag()) {
case H_leftTop:
(*it)->move(boundRect.x(), boundRect.y());
break;
case H_top:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y());
break;
case H_rightTop:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y());
break;
case H_right:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y() + boundRect.height() * 0.5);
break;
case H_rightBottom:
(*it)->move(boundRect.x() + boundRect.width(), boundRect.y() + boundRect.height());
break;
case H_bottom:
(*it)->move(boundRect.x() + boundRect.width() * 0.5, boundRect.y() + boundRect.height());
break;
case H_leftBottom:
(*it)->move(boundRect.x(), boundRect.y() + boundRect.height());
break;
case H_left:
(*it)->move(boundRect.x(), boundRect.y() + boundRect.height() * 0.5);
break;
default:
break;
}
}
}

View File

@ -0,0 +1,139 @@
#include "graphicsItem/graphicsRectItem.h"
#include "graphicsItem/itemControlHandle.h"
#include <QPainter>
GraphicsRectItem::GraphicsRectItem(const QRect &rect, bool isRound, QGraphicsItem *parent)
: GraphicsBaseItem(parent), m_bIsRound(isRound), m_dRatioX(1 / 10.0), m_dRatioY(1 / 10.0)
{
m_pen = QPen(Qt::black);
m_brush = QBrush(Qt::NoBrush);
m_lastBoudingRect = rect;
m_boundingRect = rect;
m_dWidth = rect.width();
m_dHeight = rect.height();
if (m_bIsRound) //圆角矩形添加两个圆角大小控制点
{
ItemControlHandle* pHandle1 = new ItemControlHandle(this);
pHandle1->setType(T_editShape);
pHandle1->setTag(H_edit);
m_vecHanle.push_back(pHandle1);
ItemControlHandle* pHandle2 = new ItemControlHandle(this);
pHandle2->setType(T_editShape);
pHandle2->setTag(H_edit+1);
m_vecHanle.push_back(pHandle2);
}
}
GraphicsRectItem::~GraphicsRectItem()
{
}
QPainterPath GraphicsRectItem::shape()
{
QPainterPath path;
double dHandleX = 0.0;
double dHandleY = 0.0;
if(m_dRatioX>0)
dHandleX = m_dWidth * m_dRatioX + 0.5;
if(m_dRatioY>0)
dHandleY = m_dHeight * m_dRatioY + 0.5;
if(m_bIsRound)
path.addRoundedRect(m_boundingRect, dHandleX, dHandleY);
else
path.addRect(m_boundingRect);
return path;
}
void GraphicsRectItem::updateHandles()
{
GraphicsBaseItem::updateHandles();
if(m_bIsRound && m_vecHanle.size() == H_edit + 1)
{
const QRectF& boundingRect = this->boundingRect();
//H_edit=9所以index号需要-1
m_vecHanle[H_edit -1]->move(boundingRect.right() - boundingRect.width() * m_dRatioX, boundingRect.top());
m_vecHanle[H_edit + 1 -1]->move(boundingRect.right(), boundingRect.top() + boundingRect.height() * m_dRatioY);
}
}
void GraphicsRectItem::updateCoordinate()
{
QPointF pt1, pt2, delta;
pt1 = mapToScene(transformOriginPoint());
pt2 = mapToScene(m_boundingRect.center());
delta = pt1 - pt2;
if (!parentItem())
{
prepareGeometryChange();
m_boundingRect = QRectF(-m_dWidth / 2, -m_dHeight / 2, m_dWidth, m_dHeight);
setTransform(transform().translate(delta.x(), delta.y()));
setTransformOriginPoint(m_boundingRect.center());
moveBy(-delta.x(), -delta.y());
setTransform(transform().translate(-delta.x(), -delta.y()));
updateHandles();
}
m_lastBoudingRect = m_boundingRect;
}
void GraphicsRectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->setPen(m_pen);
painter->setBrush(m_brush);
double dHandleX = 0.0;
double dHandleY = 0.0;
if(m_dRatioX>0)
dHandleX = m_dWidth * m_dRatioX + 0.5;
if(m_dRatioY>0)
dHandleY = m_dHeight * m_dRatioY + 0.5;
if(m_bIsRound)
painter->drawRoundedRect(m_boundingRect, dHandleX, dHandleY);
else
painter->drawRect(m_boundingRect);
}
void GraphicsRectItem::resize(int nHandle,double dSX, double dSY, const QPointF& basePoint)
{
switch (nHandle)
{
case H_left:
case H_right:
dSY = 1; //拖拽的是左点右点,为水平缩放,忽略垂直变化
break;
case H_top:
case H_bottom:
dSX = 1; //拖拽的是顶点底点,为垂直缩放,忽略水平变化
break;
}
QTransform trans;
//缩放是以图元原点(中心)位置为基准,所以每帧都先移动移动到想要的基准点,缩放之后再移回
trans.translate(basePoint.x(), basePoint.y());
trans.scale(dSX, dSY);
trans.translate(-basePoint.x(), -basePoint.y());
prepareGeometryChange();
m_boundingRect = trans.mapRect(m_lastBoudingRect);
m_dWidth = m_boundingRect.width();
m_dHeight = m_boundingRect.height();
updateHandles();
}
void GraphicsRectItem::move(const QPointF& point)
{
moveBy(point.x(), point.y());
}

View File

@ -0,0 +1,53 @@
#include "graphicsItem/itemControlHandle.h"
#include <QPainter>
#define HNDLE_SIZE 6
ItemControlHandle::ItemControlHandle(QGraphicsItem *parent)
: QGraphicsRectItem(-HNDLE_SIZE / 2,
-HNDLE_SIZE / 2,
HNDLE_SIZE,
HNDLE_SIZE, parent)
{
m_type = T_resize;
m_tag = H_none;
}
ItemControlHandle::~ItemControlHandle()
{
}
void ItemControlHandle::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->setPen(Qt::SolidLine);
painter->setRenderHint(QPainter::Antialiasing, true);
if(m_type==T_resize)
{
painter->setBrush(Qt::white);
painter->drawRect(rect());
}
else if(m_type==T_editShape)
{
painter->setBrush(Qt::green);
painter->drawEllipse(rect().center(), HNDLE_SIZE / 2, HNDLE_SIZE / 2);
}
}
void ItemControlHandle::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
QGraphicsRectItem::hoverEnterEvent(event);
}
void ItemControlHandle::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
QGraphicsRectItem::hoverLeaveEvent(event);
}
void ItemControlHandle::move(double x, double y)
{
setPos(x, y);
}

View File

@ -24,6 +24,9 @@
#include "FloatingDockContainer.h"
#include "DockComponentsFactory.h"
#include "drawingPanel.h"
#include "graphicElementsPanel.h"
using namespace ads;
@ -38,40 +41,27 @@ CMainWindow::CMainWindow(QWidget *parent)
DockManager = new CDockManager(this);
// Set central widget
QPlainTextEdit* w = new QPlainTextEdit();
w->setPlaceholderText("This is the central editor. Enter your text here.");
m_pDrawingPanel = new DrawingPanel();
CDockWidget* CentralDockWidget = new CDockWidget("CentralWidget");
CentralDockWidget->setWidget(w);
CentralDockWidget->setWidget(m_pDrawingPanel);
auto* CentralDockArea = DockManager->setCentralWidget(CentralDockWidget);
CentralDockArea->setAllowedAreas(DockWidgetArea::OuterDockAreas);
// create other dock widgets
QTableWidget* table = new QTableWidget();
table->setColumnCount(3);
table->setRowCount(10);
CDockWidget* TableDockWidget = new CDockWidget("Table 1");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, TableDockWidget);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
m_pGraphicElementsPanel = new GraphicElementsPanel();
CDockWidget* GrapicElementsDockWidget = new CDockWidget(QString::fromWCharArray(L"图元面板"));
GrapicElementsDockWidget->setWidget(m_pGraphicElementsPanel);
GrapicElementsDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
GrapicElementsDockWidget->resize(400, 150);
GrapicElementsDockWidget->setMinimumSize(200,150);
auto TableArea = DockManager->addDockWidget(DockWidgetArea::LeftDockWidgetArea, GrapicElementsDockWidget);
ui->menuView->addAction(GrapicElementsDockWidget->toggleViewAction());
table = new QTableWidget();
table->setColumnCount(5);
table->setRowCount(1020);
TableDockWidget = new CDockWidget("Table 2");
TableDockWidget->setWidget(table);
TableDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
TableDockWidget->resize(250, 150);
TableDockWidget->setMinimumSize(200,150);
DockManager->addDockWidget(DockWidgetArea::BottomDockWidgetArea, TableDockWidget, TableArea);
ui->menuView->addAction(TableDockWidget->toggleViewAction());
QTableWidget* propertiesTable = new QTableWidget();
propertiesTable->setColumnCount(3);
propertiesTable->setRowCount(10);
CDockWidget* PropertiesDockWidget = new CDockWidget("Properties");
CDockWidget* PropertiesDockWidget = new CDockWidget(QString::fromWCharArray(L"属性编辑器"));
PropertiesDockWidget->setWidget(propertiesTable);
PropertiesDockWidget->setMinimumSizeHintMode(CDockWidget::MinimumSizeHintFromDockWidget);
PropertiesDockWidget->resize(250, 150);
@ -79,7 +69,8 @@ CMainWindow::CMainWindow(QWidget *parent)
DockManager->addDockWidget(DockWidgetArea::RightDockWidgetArea, PropertiesDockWidget, CentralDockArea);
ui->menuView->addAction(PropertiesDockWidget->toggleViewAction());
createPerspectiveUi();
//createPerspectiveUi();
connect(m_pGraphicElementsPanel,SIGNAL(addGraphicsItem(GraphicsItemType&)),m_pDrawingPanel,SLOT(onSignal_addGraphicsItem(GraphicsItemType&)));
}
CMainWindow::~CMainWindow()

View File

@ -0,0 +1,134 @@
#include "util/baseSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h>
OperationMode BaseSelector::ms_opMode = OM_none;
QPointF BaseSelector::ms_ptMouseDown(0.0,0.0);
QPointF BaseSelector::ms_ptMouseLast(0.0,0.0);
int BaseSelector::ms_nDragHandle = 0;
BaseSelector::BaseSelector(QObject *parent)
: QObject(parent)
{
m_type = ST_base;
m_bHoverOnHandel = false;
}
BaseSelector::~BaseSelector()
{
}
void BaseSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
if (event->button() != Qt::LeftButton)
return;
ms_ptMouseDown = event->scenePos();
ms_ptMouseLast = event->scenePos();
if(!m_bHoverOnHandel)
scene->callParentEvent(event); //此处是通过触发QGraphicsScene的事件函数来取消所有被选中item的选中状态
ms_opMode = OM_none;
GraphicsBaseItem* item = nullptr;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1) //只有一个选中
{
item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
}
}
else if (items.count() > 1) //选中多个
{
ms_opMode = OM_move;
setCursor(scene, Qt::ClosedHandCursor);
}
if(ms_opMode == OM_none)
{
QGraphicsView *view = scene->getView();
if(view)
view->setDragMode(QGraphicsView::RubberBandDrag);
}
}
void BaseSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
ms_ptMouseLast = event->scenePos();
GraphicsBaseItem* item = nullptr;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item)
{
if(ms_nDragHandle != H_none && ms_opMode == OM_scale)
{
QPointF basePoint = item->getSymmetricPointPos(ms_nDragHandle);
if(basePoint.x() == 0)
basePoint.setX(1);
if(basePoint.y() == 0)
basePoint.setY(1);
//计算缩放倍数
QPointF iniDelta = item->mapFromScene(ms_ptMouseDown) - basePoint;
QPointF lastDelta = item->mapFromScene(ms_ptMouseLast) - basePoint;
double sx = lastDelta.x() / iniDelta.x();
double sy = lastDelta.y() / iniDelta.y();
item->resize(ms_nDragHandle, sx, sy, basePoint);
}
}
}
}
void BaseSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
if (event->scenePos() == ms_ptMouseDown)
ms_opMode = OM_none;
setCursor(scene, Qt::ArrowCursor);
GraphicsBaseItem* item = nullptr;
QList<QGraphicsItem *> items = scene->selectedItems();
if (items.count() == 1)
{
item = qgraphicsitem_cast<GraphicsBaseItem*>(items.first());
if(item && (ms_opMode == OM_scale || ms_opMode == OM_edit) && ms_ptMouseLast != ms_ptMouseDown)
{
item->updateCoordinate();
}
else if(item && ms_opMode == OM_move && ms_ptMouseLast != ms_ptMouseDown)
{
item->setPos(ms_ptMouseDown + (ms_ptMouseLast - ms_ptMouseDown));
}
}
if(ms_opMode == OM_none)
{
QGraphicsView *view = scene->getView();
if(view)
view->setDragMode(QGraphicsView::NoDrag);
}
ms_opMode = OM_none;
m_bHoverOnHandel = false;
ms_nDragHandle = H_none;
scene->callParentEvent(event);
}
void BaseSelector::setCursor(DesignerScene *scene, const QCursor &cursor)
{
QGraphicsView *view = scene->getView();
if (view)
view->setCursor(cursor);
}

View File

@ -0,0 +1,68 @@
#include "util/creatingSelector.h"
#include "graphicsItem/graphicsRectItem.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
CreatingSelector::CreatingSelector(QObject *parent)
: BaseSelector(parent)
{
m_type = ST_cerating;
m_pCreatingItem = nullptr;
}
CreatingSelector::~CreatingSelector()
{
}
void CreatingSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
if (event->button() != Qt::LeftButton)
return;
scene->clearSelection();
ms_ptMouseDown = event->scenePos();
ms_ptMouseLast = event->scenePos();
switch (m_creatingType) {
case GIT_rect:
m_pCreatingItem = new GraphicsRectItem(QRect(1, 1, 1, 1));
break;
case GIT_roundRect:
m_pCreatingItem = new GraphicsRectItem(QRect(1, 1, 1, 1), true);
break;
default:
break;
}
ms_ptMouseDown += QPoint(2, 2);
m_pCreatingItem->setPos(event->scenePos());
scene->addItem(m_pCreatingItem);
m_pCreatingItem->setSelected(true);
ms_opMode = OM_scale;
ms_nDragHandle = H_rightBottom;
}
void CreatingSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
setCursor(scene, Qt::CrossCursor);
BaseSelector::mouseMoveEvent(event, scene);
}
void CreatingSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
BaseSelector::mouseReleaseEvent(event, scene);
if (event->scenePos() == (ms_ptMouseDown - QPoint(2, 2))) //最小拖动范围
{
if(m_pCreatingItem)
{
m_pCreatingItem->setSelected(false);
scene->removeItem(m_pCreatingItem);
delete m_pCreatingItem;
m_pCreatingItem = nullptr;
}
}
emit setWorkingSelector(ST_base);
}

View File

@ -0,0 +1,28 @@
#include "util/selectionSelector.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
SelectionSelector::SelectionSelector(QObject *parent)
: BaseSelector(parent)
{
m_opMode = OM_selection;
}
SelectionSelector::~SelectionSelector()
{
}
void SelectionSelector::mousePressEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
BaseSelector::mousePressEvent(event,scene);
}
void SelectionSelector::mouseMoveEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
}
void SelectionSelector::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, DesignerScene* scene)
{
}

View File

@ -0,0 +1,65 @@
#include "util/selectorManager.h"
#include "util/creatingSelector.h"
SelectorManager* SelectorManager::m_pInstance = nullptr;
SelectorManager::SelectorManager(QObject *parent)
: QObject(parent)
{
static CGarbo garbo; //用来是释放单例资源的静态成员变量
//创建所有的selector
BaseSelector* baseSelector = new BaseSelector(this);
connect(baseSelector, SIGNAL(setWorkingSelector(SelectorType)), this, SLOT(onSignal_setWorkingSelector(SelectorType)));
m_vecSelectors.push_back(baseSelector);
CreatingSelector* creatingSelector = new CreatingSelector(this);
connect(creatingSelector, SIGNAL(setWorkingSelector(SelectorType)), this, SLOT(onSignal_setWorkingSelector(SelectorType)));
m_vecSelectors.push_back(creatingSelector);
m_curSelector = ST_base;
}
SelectorManager::~SelectorManager()
{
//析构所有的selector因为是通过基类指针析构所以基类的析构函数必须为虚函数
// for(auto it = m_vecSelectors.begin(); it != m_vecSelectors.end(); it++)
// delete (*it);
}
SelectorManager* SelectorManager::getInstance()
{
if(m_pInstance == nullptr)
{
m_pInstance = new SelectorManager();
}
return m_pInstance;
}
BaseSelector* SelectorManager::getWorkingSelector()
{
for(auto it = m_vecSelectors.begin(); it != m_vecSelectors.end(); it++)
{
if((*it)->getSelectorType()==m_curSelector)
{
return (*it);
}
}
return nullptr;
}
void SelectorManager::setDrawGraphicsItem(GraphicsItemType item)
{
for(auto it = m_vecSelectors.begin(); it != m_vecSelectors.end(); it++)
{
if((*it)->getSelectorType()==ST_cerating)
{
CreatingSelector* creatingSelector = dynamic_cast<CreatingSelector*>(*it);
creatingSelector->setCreatingItem(item);
}
}
}
void SelectorManager::onSignal_setWorkingSelector(SelectorType s)
{
setWorkingSelector(s);
}

41
ui/drawingPanel.ui Normal file
View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>drawingPanel</class>
<widget class="QWidget" name="drawingPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>801</width>
<height>501</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="mainLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
<resources>
<include location="../resource/PowerDesigner.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>graphicElementsPanel</class>
<widget class="QWidget" name="graphicElementsPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>167</width>
<height>721</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="tabPosition">
<enum>QTabWidget::South</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>基本图元</string>
</attribute>
<widget class="QPushButton" name="pushBtn_rect">
<property name="geometry">
<rect>
<x>30</x>
<y>20</y>
<width>81</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>直角矩形</string>
</property>
</widget>
<widget class="QPushButton" name="pushBtn_roundRect">
<property name="geometry">
<rect>
<x>30</x>
<y>100</y>
<width>81</width>
<height>51</height>
</rect>
</property>
<property name="text">
<string>圆角矩形</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>电力图元</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -20,14 +20,20 @@
<x>0</x>
<y>0</y>
<width>1284</width>
<height>21</height>
<height>33</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<widget class="QMenu" name="menuFile">
<property name="title">
<string>View</string>
<string>文件(F)</string>
</property>
</widget>
<widget class="QMenu" name="menuView">
<property name="title">
<string>视图(V)</string>
</property>
</widget>
<addaction name="menuFile"/>
<addaction name="menuView"/>
</widget>
<widget class="QToolBar" name="toolBar">
@ -40,7 +46,202 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionNew"/>
<addaction name="actionOpen"/>
<addaction name="actionSave"/>
<addaction name="separator"/>
<addaction name="actionCopy"/>
<addaction name="actionCut"/>
<addaction name="actionPast"/>
<addaction name="actionDelete"/>
<addaction name="separator"/>
<addaction name="actionZoomIn"/>
<addaction name="actionZoomOut"/>
<addaction name="actionZoomFit"/>
<addaction name="actionGrid"/>
<addaction name="separator"/>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<action name="actionNew">
<property name="icon">
<iconset theme="document-new"/>
</property>
<property name="text">
<string>新建</string>
</property>
<property name="toolTip">
<string>新建(N)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionOpen">
<property name="icon">
<iconset theme="document-open"/>
</property>
<property name="text">
<string>打开</string>
</property>
<property name="toolTip">
<string>打开(O)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionSave">
<property name="icon">
<iconset theme="document-save"/>
</property>
<property name="text">
<string>保存</string>
</property>
<property name="toolTip">
<string>保存(S)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionCopy">
<property name="icon">
<iconset theme="edit-copy"/>
</property>
<property name="text">
<string>复制</string>
</property>
<property name="toolTip">
<string>复制(C)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionCut">
<property name="icon">
<iconset theme="edit-cut"/>
</property>
<property name="text">
<string>剪切</string>
</property>
<property name="toolTip">
<string>剪切(T)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionPast">
<property name="icon">
<iconset theme="edit-paste"/>
</property>
<property name="text">
<string>粘贴</string>
</property>
<property name="toolTip">
<string>粘贴(P)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionDelete">
<property name="icon">
<iconset theme="edit-delete"/>
</property>
<property name="text">
<string>删除</string>
</property>
<property name="toolTip">
<string>删除(D)</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionZoomIn">
<property name="icon">
<iconset theme="zoom-in"/>
</property>
<property name="text">
<string>放大</string>
</property>
<property name="toolTip">
<string>放大</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionZoomOut">
<property name="icon">
<iconset theme="zoom-out"/>
</property>
<property name="text">
<string>缩小</string>
</property>
<property name="toolTip">
<string>缩小</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionZoomFit">
<property name="icon">
<iconset theme="zoom-fit-best"/>
</property>
<property name="text">
<string>自适应</string>
</property>
<property name="toolTip">
<string>自适应</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionGrid">
<property name="text">
<string>网格</string>
</property>
<property name="toolTip">
<string>网格</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionUndo">
<property name="icon">
<iconset theme="edit-undo"/>
</property>
<property name="text">
<string>撤销</string>
</property>
<property name="toolTip">
<string>撤销</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
<action name="actionRedo">
<property name="icon">
<iconset theme="edit-redo"/>
</property>
<property name="text">
<string>重做</string>
</property>
<property name="toolTip">
<string>重做</string>
</property>
<property name="menuRole">
<enum>QAction::MenuRole::NoRole</enum>
</property>
</action>
</widget>
<resources/>
<connections/>