添加项目文件。

This commit is contained in:
keyeslll
2023-02-28 14:50:28 +08:00
commit e20fa428dd
187 changed files with 18135 additions and 0 deletions

View File

@ -0,0 +1,504 @@

#include "DrawShapeView.hpp"
#include <QFileDialog>
DrawShapeView* DrawShapeView::instance = nullptr;
DrawShapeView::DrawShapeView(QWidget* parent) :
m_scene(new QGraphicsScene())
{
if (parent != Q_NULLPTR)
{
this->setParent(parent);
}
m_scene->setSceneRect(-3000, -3000, 6000, 6000);
this->setScene(m_scene);
this->resize(1204, 720);
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->setRenderHint(QPainter::Antialiasing);
this->setMouseTracking(true);
/*以鼠标中心进行缩放*/
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);//设置视口变换的锚点,这个属性控制当视图做变换时应该如何摆放场景的位置
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
MenuInit();
ParamInit();
}
DrawShapeView* DrawShapeView::getInst()
{
draw_view_lock.lock();
if (DrawShapeView::instance == nullptr)
{
DrawShapeView::instance = new DrawShapeView();
}
draw_view_lock.unlock();
return DrawShapeView::instance;
}
void DrawShapeView::FitShowImage(const QPixmap& pixmap)
{
if (pixmap != m_cur_pixmap)
{
m_cur_pixmap = pixmap;
}
m_pixmap_item->setPixmap(m_cur_pixmap);
qreal w_ratio = 1.0 * this->width() / m_cur_pixmap.width();
qreal h_ratio = 1.0 * this->height() / m_cur_pixmap.height();
if (w_ratio > h_ratio)
{
m_scale = h_ratio;
}
else
{
m_scale = w_ratio;
}
m_transform.reset();
m_transform.scale(m_scale, m_scale);
this->setTransform(m_transform);
m_centerPos = QPointF(m_cur_pixmap.width() * 0.5, m_cur_pixmap.height() * 0.5);
centerOn(m_centerPos);
}
void DrawShapeView::FitShowImage(const QPixmap& pixmap, ShapeDataStruct& _shape_data)
{
//shape_data = _shape_data;
for (auto elem : shape_items)
{
m_scene->removeItem(elem);
}
shape_items.clear();
cur_shape_item = nullptr;
FitShowImage(pixmap);
this->show();
}
HalconCpp::HRegion DrawShapeView::GetHRegionFromData(const ShapeDataStruct& shape_data)
{
HalconCpp::HRegion region_add;
HalconCpp::HRegion region_result;
HalconCpp::GenEmptyRegion(&region_result);
for (size_t i = 0; i < shape_data.shapePolygon.size(); i++)
{
HalconCpp::HTuple Hrow;
HalconCpp::HTuple Hcol;
for (int j = 0; j < shape_data.shapePolygon[i].length(); j++)
{
Hrow.Append(shape_data.shapePolygon[i][j].y());
Hcol.Append(shape_data.shapePolygon[i][j].x());
}
region_add.GenRegionPolygonFilled(Hrow, Hcol);
if (shape_data.shapeMode[i] == ShapeMode::mAdd)
{
HalconCpp::Union2(region_add, region_result, &region_result);
}
else
{
HalconCpp::Difference(region_result, region_add, &region_result);
}
}
return region_result;
}
void DrawShapeView::MenuInit()
{
m_menu = new QMenu(QStringLiteral("右键菜单"), this);
QAction* actOpenImage = new QAction(QStringLiteral("选择图片"));
QAction* actFitImage = new QAction(QStringLiteral("重置显示"));
QAction* actDrawLine = new QAction(QStringLiteral("绘制直线"));
QMenu* mAddShape = new QMenu(QStringLiteral("相加图形"));
QAction* actDrawRectangle1Add = new QAction(QStringLiteral("正矩形"));
QAction* actDrawRectangle2Add = new QAction(QStringLiteral("斜矩形"));
QAction* actDrawPolygonAdd = new QAction(QStringLiteral("多边形"));
QAction* actDrawFreeDrawAdd = new QAction(QStringLiteral("涂鸦"));
mAddShape->addAction(actDrawRectangle1Add);
mAddShape->addAction(actDrawRectangle2Add);
mAddShape->addAction(actDrawPolygonAdd);
mAddShape->addAction(actDrawFreeDrawAdd);
QMenu* mDivShape = new QMenu(QStringLiteral("相减图形"));
QAction* actDrawRectangle1Div = new QAction(QStringLiteral("正矩形"));
QAction* actDrawRectangle2Div = new QAction(QStringLiteral("斜矩形"));
QAction* actDrawPolygonDiv = new QAction(QStringLiteral("多边形"));
QAction* actDrawFreeDrawDiv = new QAction(QStringLiteral("涂鸦"));
mDivShape->addAction(actDrawRectangle1Div);
mDivShape->addAction(actDrawRectangle2Div);
mDivShape->addAction(actDrawPolygonDiv);
mDivShape->addAction(actDrawFreeDrawDiv);
QAction* actComform = new QAction(QStringLiteral("确认"));
QAction* actCancel = new QAction(QStringLiteral("取消"));
m_menu->addAction(actOpenImage);
m_menu->addAction(actFitImage);
m_menu->addAction(actDrawLine);
m_menu->addMenu(mAddShape);
m_menu->addMenu(mDivShape);
m_menu->addAction(actComform);
m_menu->addAction(actCancel);
connect(actOpenImage, SIGNAL(triggered()), this, SLOT(onOpenImage()));
connect(actFitImage, SIGNAL(triggered()), this, SLOT(onFitImageShow()));
connect(actDrawLine, SIGNAL(triggered()), this, SLOT(onDrawLineShape()));
connect(actDrawRectangle1Add, &QAction::triggered, this, [=]() {
this->onDrawRectangle1(ShapeMode::mAdd); });
connect(actDrawRectangle2Add, &QAction::triggered, this, [=]() {
this->onDrawRectangle2(ShapeMode::mAdd); });
connect(actDrawPolygonAdd, &QAction::triggered, this, [=]() {
this->onDrawPolygon(ShapeMode::mAdd); });
connect(actDrawFreeDrawAdd, &QAction::triggered, this, [=]() {
this->onDrawFreeDraw(ShapeMode::mAdd); });
connect(actDrawRectangle1Div, &QAction::triggered, this, [=]() {
this->onDrawRectangle1(ShapeMode::mDiv); });
connect(actDrawRectangle2Div, &QAction::triggered, this, [=]() {
this->onDrawRectangle2(ShapeMode::mDiv); });
connect(actDrawPolygonDiv, &QAction::triggered, this, [=]() {
this->onDrawPolygon(ShapeMode::mDiv); });
connect(actDrawFreeDrawDiv, &QAction::triggered, this, [=]() {
this->onDrawFreeDraw(ShapeMode::mDiv); });
connect(actComform, SIGNAL(triggered()), this, SLOT(onDrawComform()));
connect(actCancel, SIGNAL(triggered()), this, SLOT(onDrawCancel()));
}
void DrawShapeView::ParamInit()
{
m_pixmap_item = new QGraphicsPixmapItem();
m_draw_path_item = new QGraphicsPathItem();
m_draw_poly = new QPolygonF();
v_hint_line = new QGraphicsLineItem();
h_hint_line = new QGraphicsLineItem();
m_pixmap_item->setZValue(0);
m_scene->addItem(m_pixmap_item);
m_scene->addItem(m_draw_path_item);
}
void DrawShapeView::onOpenImage()
{
cur_image_name.clear();
cur_image_name = QFileDialog::getOpenFileName(nullptr,
"Select an image",
"C:",
"Images (*.png *.jpeg *.jpg *.tiff *.bmp)"
);
if (cur_image_name.length() == 0)
{
return;
}
if (m_cur_pixmap.load(cur_image_name))
{
FitShowImage(m_cur_pixmap);
}
this->repaint();
}
void DrawShapeView::onFitImageShow()
{
FitShowImage(m_cur_pixmap);
}
void DrawShapeView::onDrawLineShape()
{
//draw_shape = EShapeType::sLine;
//view_mode = ViewMode::tDrawing;
//m_scene->addItem(v_hint_line);
//m_scene->addItem(h_hint_line);
cur_shape_item = new ShapeItemLine();
shape_items.append(cur_shape_item);
m_scene->addItem(cur_shape_item);
}
void DrawShapeView::onDrawRectangle1(ShapeMode mode)
{
if (mode == ShapeMode::mAdd)
{
draw_shape = EShapeType::sRectangle1Add;
shape_mode = ShapeMode::mAdd;
}
else
{
draw_shape = EShapeType::sRectangle1Div;
shape_mode = ShapeMode::mDiv;
}
//view_mode = ViewMode::tDrawing;
//m_scene->addItem(v_hint_line);
//m_scene->addItem(h_hint_line);
cur_shape_item = new ShapeItemRect1(shape_mode);
shape_items.append(cur_shape_item);
m_scene->addItem(cur_shape_item);
}
void DrawShapeView::onDrawRectangle2(ShapeMode mode)
{
if (mode == ShapeMode::mAdd)
{
draw_shape = EShapeType::sRectangle2Add;
shape_mode = ShapeMode::mAdd;
}
else
{
draw_shape = EShapeType::sRectangle2Div;
shape_mode = ShapeMode::mDiv;
}
cur_shape_item = new ShapeItemRect2(shape_mode);
shape_items.append(cur_shape_item);
m_scene->addItem(cur_shape_item);
//view_mode = ViewMode::tDrawing;
//m_scene->addItem(v_hint_line);
//m_scene->addItem(h_hint_line);
}
void DrawShapeView::onDrawPolygon(ShapeMode mode)
{
if (mode == ShapeMode::mAdd)
{
draw_shape = EShapeType::sPolygonAdd;
shape_mode = ShapeMode::mAdd;
}
else
{
draw_shape = EShapeType::sPolygonDiv;
shape_mode = ShapeMode::mDiv;
}
view_mode = ViewMode::tDrawing;
m_scene->addItem(v_hint_line);
m_scene->addItem(h_hint_line);
}
void DrawShapeView::onDrawFreeDraw(ShapeMode mode)
{
}
void DrawShapeView::onDrawComform()
{
shape_data.shapePolygon.clear();
shape_data.shapeMode.clear();
for (auto& elem : shape_items)
{
shape_data.shapePolygon.append(elem->GetShapePoygonF());
shape_data.shapeMode.append(elem->GetShapeMode());
}
emit RegionComform(shape_data);
this->hide();
}
void DrawShapeView::onDrawCancel()
{
}
void DrawShapeView::drawFinished()
{
m_scene->removeItem(v_hint_line);
m_scene->removeItem(h_hint_line);
if (m_draw_poly->count() > 1)
{
//m_draw_poly->last() = m_draw_poly->first();
//shape_data.shapePolygon.append(*m_draw_poly);
//shape_data.shapeType.append(draw_shape);
//shape_data.shapeMode.append(shape_mode);
//tmpPath.clear();
//tmpPath.addPolygon(*m_draw_poly);
//m_draw_path_item->setPath(tmpPath);
if (draw_shape == EShapeType::sPolygonAdd || draw_shape == EShapeType::sPolygonDiv)
{
cur_shape_item = new ShapeItemPolygon(*m_draw_poly, shape_mode, QPointF(0, 0));
m_scene->addItem(cur_shape_item);
shape_items.append(cur_shape_item);
}
m_draw_poly->clear();
m_draw_path_item->setPath(QPainterPath());
}
view_mode = ViewMode::tNone;
shape_mode = ShapeMode::mNone;
draw_shape = EShapeType::sNone;
}
void DrawShapeView::drawHintInfo(QPainter* painter)
{
m_hint_str.clear();
m_hint_str = QString("mouse:%1,%2").arg(m_cur_pos_view.x()).arg(m_cur_pos_view.y());
m_hint_str.append(QString(" - mouse scene:%1,%2").arg(m_cur_pos_scene.x()).arg(m_cur_pos_scene.y()));
painter->setPen(Qt::white);
painter->setBrush(Qt::NoBrush);
painter->drawText(10, 25, m_hint_str);
}
void DrawShapeView::drawCurrentShape(QPainter* painter)
{
if (view_mode != ViewMode::tDrawing)
{
return;
}
//painter->setPen(Qt::NoPen);
//painter->setBrush(m_hint_bg_color);
//for (auto tmp_polygon : shape_data.shapePolygon) {
// QPainterPath tmp_view_path;
// QPolygonF tmp_polygon_view;
// for (auto _point : tmp_polygon)
// {
// tmp_polygon_view.append(mapFromScene(_point));
// }
// if (!tmp_polygon_view.isEmpty())
// {
// tmp_view_path.addPolygon(tmp_polygon_view);
// painter->drawPath(tmp_view_path);
// }
//}
}
void DrawShapeView::mousePressEvent(QMouseEvent* event)
{
QGraphicsView::mousePressEvent(event);
m_lastMousePos = mapToScene(event->pos());
if (event->button() == Qt::RightButton)
{
if (view_mode != ViewMode::tDrawing)
{
m_menu->exec(mapToGlobal(event->pos()));
}
else
{
drawFinished();
}
}
else if (event->button() == Qt::LeftButton)
{
if (view_mode == ViewMode::tDrawing)
{
if (m_draw_poly->count() == 0)
{
m_draw_poly->append(m_lastMousePos);
}
m_draw_poly->append(m_lastMousePos);
}
switch (draw_shape)
{
case EShapeType::sLine:
case EShapeType::sRectangle1Add:
case EShapeType::sRectangle1Div:
if (m_draw_poly->count() == 3)
{
drawFinished();
}
break;
case EShapeType::sRectangle2Add:
case EShapeType::sRectangle2Div:
if (m_draw_poly->count() == 4)
{
drawFinished();
}
break;
default:
break;
}
}
else if (event->button() == Qt::MiddleButton)
{
view_mode = ViewMode::tTranslate;
}
}
void DrawShapeView::mouseReleaseEvent(QMouseEvent* event)
{
QGraphicsView::mouseReleaseEvent(event);
if (event->button() == Qt::RightButton)
{
}
else if (event->button() == Qt::LeftButton)
{
}
else if (event->button() == Qt::MiddleButton)
{
if (view_mode != ViewMode::tDrawing)
{
view_mode = ViewMode::tNone;
}
}
}
void DrawShapeView::mouseMoveEvent(QMouseEvent* event)
{
QGraphicsView::mouseMoveEvent(event);
m_cur_pos_view = event->pos();
m_cur_pos_scene = mapToScene(m_cur_pos_view);
if (view_mode == ViewMode::tTranslate)
{
m_centerPos.setX(m_centerPos.x() - m_cur_pos_scene.x() + m_lastMousePos.x());
m_centerPos.setY(m_centerPos.y() - m_cur_pos_scene.y() + m_lastMousePos.y());
centerOn(m_centerPos);
}
if (view_mode == ViewMode::tDrawing)
{
v_hint_line->setLine(
m_cur_pos_scene.x(),
m_cur_pos_scene.y() - 1000,
m_cur_pos_scene.x(),
m_cur_pos_scene.y() + 1000);
h_hint_line->setLine(
m_cur_pos_scene.x() - 1000,
m_cur_pos_scene.y(),
m_cur_pos_scene.x() + 1000,
m_cur_pos_scene.y());
if (m_draw_poly->count() > 1)
{
m_draw_poly->last() = m_cur_pos_scene;
tmpPath.clear();
tmpPath.addPolygon(*m_draw_poly);
m_draw_path_item->setPath(tmpPath);
}
}
this->viewport()->repaint();
}
void DrawShapeView::wheelEvent(QWheelEvent* event)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
qreal scaleFactor = 1.0;
if (event->delta() > 0)
{
scaleFactor = 1.2;
}
else
{
scaleFactor = 1 / 1.2;
}
qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.01 || factor > 2000)
return;
scale(scaleFactor, scaleFactor);
}
void DrawShapeView::paintEvent(QPaintEvent* event)
{
QGraphicsView::paintEvent(event);
QPainter painter(this->viewport());
drawCurrentShape(&painter);
drawHintInfo(&painter);
}
void DrawShapeView::drawBackground(QPainter* painter, const QRectF& rect)
{
QGraphicsView::drawBackground(painter, rect);
painter->setBrush(m_bg_color);
painter->setPen(Qt::NoPen);
painter->drawRect(rect);
painter->setBrush(Qt::NoBrush);
painter->setPen(m_grid_pen);
painter->drawLine(-3000, 0, 3000, 0);
painter->drawLine(0, -3000, 0, 3000);
}

View File

@ -0,0 +1,124 @@
#pragma once
#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QColor>
#include <QMouseEvent>
#include <QPainter>
#include <QPaintEvent>
#include <QMenu>
#include <QGraphicsTextItem>
#include <QGraphicsPixmapItem>
#include <QScrollBar>
#include <QPainterPath>
#include <QPolygonF>
#include "DrawViewParams.h"
#include "ShapeItemLine.h"
#include "ShapeItemRect1.h"
#include "ShapeItemRect2.h"
#include "ShapeItemPolygon.h"
#include "halconcpp/HalconCpp.h"
static std::mutex draw_view_lock;
class DrawShapeView :public QGraphicsView
{
Q_OBJECT
public:
explicit DrawShapeView(QWidget* parent = Q_NULLPTR);
~DrawShapeView() {};
static DrawShapeView* instance;
static DrawShapeView* getInst();
//DrawShapeView(const DrawShapeView&);
DrawShapeView& operator=(const DrawShapeView&);
private:
class Deletor
{
public:
~Deletor()
{
if (DrawShapeView::instance != nullptr)
{
delete DrawShapeView::instance;
}
}
};
static Deletor deletor;
private:
QGraphicsScene* m_scene;
QColor m_bg_color = QColor(34, 34, 34, 255);
QColor m_grid_color = QColor(10, 10, 10, 255);
QColor m_hint_bg_color = QColor(0, 255, 0, 100);
QPen m_grid_pen = QPen(m_grid_color, 3);
QString m_hint_str;
QPoint m_cur_pos_view;
QPointF m_cur_pos_scene;
QPointF m_hint_tl;
ViewMode view_mode = ViewMode::tNone;
EShapeType draw_shape;
ShapeMode shape_mode;
ShapeDataStruct shape_data;
QList<ShapeItemBase*> shape_items;
ShapeItemBase* cur_shape_item = nullptr;
QString cur_image_name;
QPixmap m_cur_pixmap;
QPointF m_lastMousePos; // 鼠标最后按下的位置
QPointF m_centerPos; //
qreal m_scale = 1.0; // 缩放值
QTransform m_transform;
QMenu* m_menu;
QGraphicsPixmapItem* m_pixmap_item;
QGraphicsPathItem* m_draw_path_item;
QPolygonF* m_draw_poly;
QPainterPath tmpPath;
QGraphicsLineItem* v_hint_line;
QGraphicsLineItem* h_hint_line;
public:
void FitShowImage(const QPixmap& pixmap);
void FitShowImage(const QPixmap& pixmap, ShapeDataStruct& shape_data);
static HalconCpp::HRegion GetHRegionFromData(const ShapeDataStruct& shape_data);
private:
void MenuInit();
void ParamInit();
public slots:
void onOpenImage();
void onFitImageShow();
void onDrawLineShape();
void onDrawRectangle1(ShapeMode mode);
void onDrawRectangle2(ShapeMode mode);
void onDrawPolygon(ShapeMode mode);
void onDrawFreeDraw(ShapeMode mode);
void onDrawComform();
void onDrawCancel();
signals:
void DrawFinished();
void RegionComform(ShapeDataStruct shape_data);
private:
void drawFinished();
void drawHintInfo(QPainter* painter);
void drawCurrentShape(QPainter* painter);
protected:
void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
void paintEvent(QPaintEvent* event) override;
void drawBackground(QPainter* painter, const QRectF& rect) override;
};

View File

@ -0,0 +1,41 @@
#pragma once
#include <QString>
enum class ViewMode
{
tNone,
tTranslate,
tZoom,
tDrawing
};
enum class EShapeType
{
sNone,
sLine,
sRectangle1Add,
sRectangle2Add,
sPolygonAdd,
sFreeDrawAdd,
sRectangle1Div,
sRectangle2Div,
sPolygonDiv,
sFreeDrawDiv
};
enum class ShapeMode
{
mNone,
mAdd,
mDiv
};
struct ShapeDataStruct
{
QString name;
QVector<QPolygonF> shapePolygon;
QVector<EShapeType> shapeType;
QVector<ShapeMode> shapeMode;
};

View File

@ -0,0 +1,78 @@
#include "ShapeControlItem.h"
#include "ShapeItemBase.h"
//构造函数
ShapeControlItem::ShapeControlItem(QGraphicsItemGroup* parent,
ControlItemType type,
QPointF p, int style)
: QAbstractGraphicsShapeItem(parent)
{
setPos(p);
setAcceptHoverEvents(true);
handle_type = type;
this->setFlags(QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable);
bounding_rect = QRectF(-handle_size * 0.5, -handle_size * 0.5,
handle_size, handle_size);
}
void ShapeControlItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
active_states = true;
Q_UNUSED(event);
}
void ShapeControlItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
active_states = false;
Q_UNUSED(event);
}
//拖拽 鼠标感应区域
QRectF ShapeControlItem::boundingRect() const
{
return bounding_rect; //拖拽 鼠标感应区域
}
//位置重绘
void ShapeControlItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->setPen(Qt::NoPen);
if (active_states)
{
painter->setBrush(handle_active_color);
bounding_rect = QRectF(-handle_active_size * 0.5, -handle_active_size * 0.5,
handle_active_size, handle_active_size);
}
else
{
painter->setBrush(handle_color);
bounding_rect = QRectF(-handle_size * 0.5, -handle_size * 0.5,
handle_size, handle_size);
}
painter->drawRoundedRect(bounding_rect, 2, 2);
}
//鼠标事件处理
void ShapeControlItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
if (event->buttons() == Qt::LeftButton)
{
last_point = cur_point;
cur_point = this->mapToParent(event->pos());
dx = cur_point.x() - last_point.x();
dy = cur_point.y() - last_point.y();
if (this->handle_type != cCenter && this->handle_type != cRotate)
{
//结果正常、更新位置
this->setPos(cur_point);
}
}
emit PositionChanged();
}
void ShapeControlItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
QGraphicsItem::mousePressEvent(event);
}

View File

@ -0,0 +1,59 @@
#pragma once
#include <QObject>
#include <QAbstractGraphicsShapeItem>
#include <QPointF>
#include <QPen>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsScene>
#include <QCursor>
#include <QKeyEvent>
#include <QList>
#include <QDebug>
#include "DrawViewParams.h"
enum ControlItemType
{
cNone,
cCenter,
cEdgeNode,
cRotate
};
class ShapeControlItem :
public QObject
, public QAbstractGraphicsShapeItem
{
Q_OBJECT
public:
explicit ShapeControlItem(QGraphicsItemGroup* parent,
ControlItemType type,
QPointF p, int style = 1);
ControlItemType getType() { return handle_type; }
qreal getDx() { return dx; }
qreal getDy() { return dy; }
QPointF getCenterPointF() { return this->pos(); }
private:
QRectF bounding_rect;
int handle_size = 5;
int handle_active_size = 8;
bool active_states = false;
QColor handle_color = QColor(255, 255, 0, 100);
QColor handle_active_color = QColor(255, 0, 0, 100);
qreal dx;
qreal dy;
QPointF last_point;
QPointF cur_point;
ControlItemType handle_type;
signals:
void PositionChanged();
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
virtual QRectF boundingRect() const override;
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
};

View File

@ -0,0 +1,77 @@
#include "ShapeItemBase.h"
ShapeItemBase::ShapeItemBase(EShapeType type) :types(type)
{
setHandlesChildEvents(false);//设置后才能将事件传递到子元素
if (type != EShapeType::sNone) //模式选择 自定义模式用于显示亚像素轮廓和Region 不设定任何属性
{
this->setFlags(QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable |
QGraphicsItem::ItemIsFocusable);
}
this->setCursor(Qt::ArrowCursor);
activeHandle = nullptr;
bounding_rect = QRectF(0, 0, 100, 100);
ItemPath.addRect(bounding_rect);
ItemShape.addRect(bounding_rect);
}
ShapeItemBase::~ShapeItemBase()
{
}
void ShapeItemBase::focusInEvent(QFocusEvent* event)
{
Q_UNUSED(event);
this->setZValue(99);
shape_active = true;
}
void ShapeItemBase::focusOutEvent(QFocusEvent* event)
{
Q_UNUSED(event);
this->setZValue(1);
shape_active = false;
}
QRectF ShapeItemBase::boundingRect() const
{
return ItemPath.boundingRect().united(ItemShape.boundingRect());
}
QPainterPath ShapeItemBase::shape() const
{
return ItemShape.united(ItemPath);
}
void ShapeItemBase::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
QGraphicsItemGroup::paint(painter, option, widget);
painter->setPen(Qt::NoPen);
if (shape_active)
{
painter->setBrush(activeBackgroundColor);
//painter->drawRect(this->boundingRect());
}
else
{
if (m_shape_mode == ShapeMode::mAdd)
{
painter->setBrush(addBackgroundColor);
}
else
{
painter->setBrush(divBackgroundColor);
}
}
if (!ItemPath.isEmpty())
{
painter->setPen(ItemColor);
//painter->setBrush(Qt::NoBrush);
painter->drawPath(ItemPath);
}
}

View File

@ -0,0 +1,66 @@
#pragma once
#include <qobject.h>
#include<QGraphicsItemGroup>
#include "DrawViewParams.h"
#include "ShapeControlItem.h"
class ShapeItemBase :
public QObject, public QGraphicsItemGroup
{
Q_OBJECT
public:
ShapeItemBase(EShapeType type);
virtual ~ShapeItemBase();
void SetZoomVal(qreal ZoomVal) { scaler = ZoomVal; }
qreal GetContrSize() const { return ContrSize; }
QPolygonF GetShapePoygonF()
{
//if (!itemPolygon.isClosed())
//{
// itemPolygon.append(itemPolygon.first());
//}
for (int i = 0; i < itemPolygon.count(); i++)
{
itemPolygon[i] = mapToScene(itemPolygon[i]);
}
return itemPolygon;
}
ShapeMode GetShapeMode() { return m_shape_mode; }
private:
virtual void shapeInit() = 0;
public slots:
virtual void calculateShape() = 0;
virtual void rotateShape(qreal delta) {};
protected:
void focusInEvent(QFocusEvent* event) override;
void focusOutEvent(QFocusEvent* event) override;
QRectF boundingRect() const override;
QPainterPath shape() const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
protected:
ShapeControlItem* activeHandle;
QList<ShapeControlItem* > ControlList;
QRectF bounding_rect;
qreal scaler; //缩放系数
const qreal ContrSize = 8; //控制点尺寸
EShapeType types; //枚举类型
QColor ItemColor = QColor(0, 100, 200); //线条颜色
QColor BackgroundColor = QColor(0, 160, 230, 100); //填充背景颜色
QColor addBackgroundColor = QColor(0, 255, 0, 100); //填充背景颜色
QColor divBackgroundColor = QColor(255, 0, 0, 50); //填充背景颜色
QColor activeBackgroundColor = QColor(255, 255, 0, 100); //填充背景颜色
bool shape_active = false;
QString ItemDiscrib = QString::fromLocal8Bit("描述");
ShapeMode m_shape_mode = ShapeMode::mNone;
QPointF Center; //中心点
QPainterPath ItemShape; //有边框区域
QPainterPath ItemPath; //有边框区域
QPolygonF itemPolygon;
};

View File

@ -0,0 +1,67 @@
#include "ShapeItemLine.h"
ShapeItemLine::ShapeItemLine(QPointF pos) :
ShapeItemBase(EShapeType::sLine)
{
this->setPos(pos);
shapeInit();
}
ShapeItemLine::~ShapeItemLine()
{
}
void ShapeItemLine::calculateShape()
{
if (this->sender() == nullptr)
{
ControlList[1]->setX(0.5 * (ControlList[0]->x() + ControlList[2]->x()));
ControlList[1]->setY(0.5 * (ControlList[0]->y() + ControlList[2]->y()));
ItemPath.clear();
itemPolygon[0] = ControlList[0]->getCenterPointF();
itemPolygon[1] = ControlList[2]->getCenterPointF();
ItemPath.addPolygon(itemPolygon);
ItemPath.closeSubpath();
ItemShape.clear();
ItemShape.addRect(ItemPath.boundingRect());
}
else
{
activeHandle = dynamic_cast<ShapeControlItem*>(this->sender());
if (activeHandle->getType() == cCenter)
{
//this->moveBy(activeHandle->getDx(), activeHandle->getDy());
}
else if (activeHandle->getType() == cRotate)
{
}
else {
ControlList[1]->setX(0.5 * (ControlList[0]->x() + ControlList[2]->x()));
ControlList[1]->setY(0.5 * (ControlList[0]->y() + ControlList[2]->y()));
ItemPath.clear();
itemPolygon[0] = ControlList[0]->getCenterPointF();
itemPolygon[1] = ControlList[2]->getCenterPointF();
ItemPath.addPolygon(itemPolygon);
ItemPath.closeSubpath();
ItemShape.clear();
ItemShape.addRect(ItemPath.boundingRect());
}
}
}
void ShapeItemLine::shapeInit()
{
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 10)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cCenter, QPointF(50, 50)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 90)));
itemPolygon.append(QPointF(ControlList[0]->x(), ControlList[0]->y()));
itemPolygon.append(QPointF(ControlList[2]->x(), ControlList[2]->y()));
for (auto elem : ControlList)
{
connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape()));
}
calculateShape();
}

View File

@ -0,0 +1,15 @@
#include "ShapeItemBase.h"
class ShapeItemLine
:public ShapeItemBase
{
public:
ShapeItemLine(QPointF pos = QPointF(0, 0));
~ShapeItemLine();
private:
void calculateShape() override;
void shapeInit() override;
};

View File

@ -0,0 +1,66 @@
#include "ShapeItemPolygon.h"
ShapeItemPolygon::ShapeItemPolygon(QPolygonF polygon, ShapeMode shape_mode, QPointF pos) :
ShapeItemBase(EShapeType::sLine)
{
m_shape_mode = shape_mode;
itemPolygon = polygon;
this->setPos(pos);
shapeInit();
}
ShapeItemPolygon::~ShapeItemPolygon()
{
}
void ShapeItemPolygon::calculateShape()
{
if (this->sender() == nullptr)
{
sizeChanged();
}
else
{
activeHandle = dynamic_cast<ShapeControlItem*>(this->sender());
if (activeHandle->getType() == cCenter)
{
//this->moveBy(activeHandle->getDx(), activeHandle->getDy());
}
else if (activeHandle->getType() == cRotate)
{
}
else {
sizeChanged();
}
}
}
void ShapeItemPolygon::sizeChanged()
{
ItemPath.clear();
int i = 0;
for (auto elem : ControlList)
{
itemPolygon[i] = elem->getCenterPointF();
i++;
}
ItemPath.addPolygon(itemPolygon);
ItemPath.closeSubpath();
ItemShape.clear();
ItemShape.addRect(ItemPath.boundingRect());
}
void ShapeItemPolygon::shapeInit()
{
for (auto elem : itemPolygon)
{
ControlList.append(new ShapeControlItem(this, cEdgeNode, elem));
}
for (auto elem : ControlList)
{
connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape()));
}
calculateShape();
}

View File

@ -0,0 +1,15 @@
#include "ShapeItemBase.h"
class ShapeItemPolygon
:public ShapeItemBase
{
public:
ShapeItemPolygon(QPolygonF polygon, ShapeMode shape_mode, QPointF pos = QPointF(0, 0));
~ShapeItemPolygon();
private:
void calculateShape() override;
void sizeChanged();
void shapeInit() override;
};

View File

@ -0,0 +1,84 @@
#include "ShapeItemRect1.h"
ShapeItemRect1::ShapeItemRect1(ShapeMode shape_mode) :
ShapeItemBase(EShapeType::sRectangle1Add)
{
m_shape_mode = shape_mode;
shapeInit();
}
ShapeItemRect1::~ShapeItemRect1()
{
}
void ShapeItemRect1::calculateShape()
{
if (this->sender() == nullptr)
{
sizeChanged();
}
else
{
activeHandle = dynamic_cast<ShapeControlItem*>(this->sender());
if (activeHandle->getType() == cCenter)
{
//this->moveBy(activeHandle->getDx(), activeHandle->getDy());
}
else if (activeHandle->getType() == cRotate)
{
}
else {
sizeChanged();
}
}
}
void ShapeItemRect1::shapeInit()
{
ControlList.append(new ShapeControlItem(this, ControlItemType::cCenter, QPointF(50, 50)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 10)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 10)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 90)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 90)));
itemPolygon.append(QPointF(ControlList[1]->x(), ControlList[1]->y()));
itemPolygon.append(QPointF(ControlList[2]->x(), ControlList[2]->y()));
itemPolygon.append(QPointF(ControlList[3]->x(), ControlList[3]->y()));
itemPolygon.append(QPointF(ControlList[4]->x(), ControlList[4]->y()));
ControlList[2]->setVisible(false);
ControlList[4]->setVisible(false);
for (auto elem : ControlList)
{
connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape()));
}
calculateShape();
}
void ShapeItemRect1::sizeChanged()
{
activeHandle = dynamic_cast<ShapeControlItem*>(this->sender());
ControlList[0]->setX(0.5 * (ControlList[1]->x() + ControlList[3]->x()));
ControlList[0]->setY(0.5 * (ControlList[1]->y() + ControlList[3]->y()));
ControlList[2]->setX(ControlList[3]->x());
ControlList[2]->setY(ControlList[1]->y());
ControlList[4]->setX(ControlList[1]->x());
ControlList[4]->setY(ControlList[3]->y());
itemPolygon[0] = ControlList[1]->getCenterPointF();
itemPolygon[1] = ControlList[2]->getCenterPointF();
itemPolygon[2] = ControlList[3]->getCenterPointF();
itemPolygon[3] = ControlList[4]->getCenterPointF();
ItemPath.clear();
ItemPath.addPolygon(itemPolygon);
ItemPath.closeSubpath();
ItemShape.clear();
ItemShape.addRect(ItemPath.boundingRect());
}

View File

@ -0,0 +1,17 @@
#include "ShapeItemBase.h"
class ShapeItemRect1
:public ShapeItemBase
{
public:
ShapeItemRect1(ShapeMode shape_mode);
~ShapeItemRect1();
private:
void calculateShape() override;
void shapeInit() override;
void sizeChanged();
};

View File

@ -0,0 +1,103 @@
#include "ShapeItemRect2.h"
ShapeItemRect2::ShapeItemRect2(ShapeMode shape_mode, QPointF pos) :
ShapeItemBase(EShapeType::sRectangle2Add)
{
m_shape_mode = shape_mode;
shapeInit();
}
ShapeItemRect2::~ShapeItemRect2()
{
}
void ShapeItemRect2::calculateShape()
{
if (this->sender() == nullptr)
{
sizeChanged();
}
else
{
activeHandle = dynamic_cast<ShapeControlItem*>(this->sender());
if (activeHandle->getType() == cCenter)
{
//this->moveBy(activeHandle->getDx(), activeHandle->getDy());
}
else if (activeHandle->getType() == cRotate)
{
rotateShape(activeHandle->getDy());
}
else {
sizeChanged();
}
}
}
void ShapeItemRect2::rotateShape(qreal delta)
{
m_transform = this->transform();
m_transform.rotate(1);
qreal delta_angle = 1.0;
if (delta > 0)
{
delta_angle = 1.0;
}
else
{
delta_angle = -1.0;
}
m_transform = m_transform.rotate(delta_angle);
this->setTransform(m_transform);
}
void ShapeItemRect2::shapeInit()
{
ControlList.append(new ShapeControlItem(this, ControlItemType::cCenter, QPointF(50, 50)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 10)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 10)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(90, 90)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cEdgeNode, QPointF(10, 90)));
ControlList.append(new ShapeControlItem(this, ControlItemType::cRotate, QPointF(50, 10)));
itemPolygon.append(QPointF(ControlList[1]->x(), ControlList[1]->y()));
itemPolygon.append(QPointF(ControlList[2]->x(), ControlList[2]->y()));
itemPolygon.append(QPointF(ControlList[3]->x(), ControlList[3]->y()));
itemPolygon.append(QPointF(ControlList[4]->x(), ControlList[4]->y()));
ControlList[2]->setVisible(false);
ControlList[4]->setVisible(false);
for (auto elem : ControlList)
{
connect(elem, SIGNAL(PositionChanged()), this, SLOT(calculateShape()));
}
calculateShape();
}
void ShapeItemRect2::sizeChanged()
{
activeHandle = dynamic_cast<ShapeControlItem*>(this->sender());
ControlList[0]->setX(0.5 * (ControlList[1]->x() + ControlList[3]->x()));
ControlList[0]->setY(0.5 * (ControlList[1]->y() + ControlList[3]->y()));
ControlList[5]->setX(ControlList[0]->x());
ControlList[5]->setY(ControlList[1]->y());
ControlList[2]->setX(ControlList[3]->x());
ControlList[2]->setY(ControlList[1]->y());
ControlList[4]->setX(ControlList[1]->x());
ControlList[4]->setY(ControlList[3]->y());
itemPolygon[0] = ControlList[1]->getCenterPointF();
itemPolygon[1] = ControlList[2]->getCenterPointF();
itemPolygon[2] = ControlList[3]->getCenterPointF();
itemPolygon[3] = ControlList[4]->getCenterPointF();
ItemPath.clear();
ItemPath.addPolygon(itemPolygon);
ItemPath.closeSubpath();
ItemShape.clear();
ItemShape.addRect(ItemPath.boundingRect());
}

View File

@ -0,0 +1,21 @@
#include "ShapeItemBase.h"
class ShapeItemRect2
:public ShapeItemBase
{
public:
ShapeItemRect2(ShapeMode shape_mode, QPointF pos = QPointF(0, 0));
~ShapeItemRect2();
private:
QTransform m_transform;
private:
void calculateShape() override;
void rotateShape(qreal delta) override;
void shapeInit() override;
void sizeChanged();
};