505 lines
13 KiB
C++
505 lines
13 KiB
C++
|
|
#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(®ion_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, ®ion_result);
|
|
}
|
|
else
|
|
{
|
|
HalconCpp::Difference(region_result, region_add, ®ion_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);
|
|
}
|
|
|