GraphView实现测量工具

效果演示:
在这里插入图片描述
主模块代码:

MeasureGraphView::MeasureGraphView(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    m_measureType = NoType;
    m_bll = BllData::getInstance();
    m_scene = new GraphicsScene;
   connect(m_bll, &BllData::pressMeasurePosSignal, this, &MeasureGraphView::pressMeasurePosSlot);
   connect(m_bll, &BllData::returnDeletePosSignal, this, &MeasureGraphView::returnDeletePosSlot);
    // 隐藏水平/竖直滚动条
    ui.graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ui.graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    // 设置场景范围
    ui.graphicsView->setSceneRect(INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX);
    // 反锯齿
    ui.graphicsView->setRenderHints(QPainter::Antialiasing);
    m_scene->setBackgroundBrush(Qt::gray);
    ui.graphicsView->setScene(m_scene);
}
MeasureGraphView::~MeasureGraphView()
{
}
void MeasureGraphView::on_disBtn_clicked() {
    m_measureType = DistanceType;
    m_bll->setMeasureEnable(m_measureType);
}
void MeasureGraphView::on_agBtn_clicked() {
    m_measureType = AngleType;
    m_bll->setMeasureEnable(m_measureType);
}
void MeasureGraphView::on_plineBtn_clicked() {
    m_measureType = PToLineType;
    m_bll->setMeasureEnable(m_measureType);
}
void MeasureGraphView::on_deleteBtn_clicked() {
    m_bll->deleteShapeEnable();
}
void MeasureGraphView::on_clearBtn_clicked() {
    m_scene->clear();
}
void MeasureGraphView::pressMeasurePosSlot(QPointF pos, PointType type) {
    if (m_measureType == DistanceType) {
        if (type == TopLeft) {
            MeasureBase* disMeasure = new MeasureBase(DistanceType);
            m_shapeList.append(disMeasure);
            m_scene->addItem(disMeasure);
            disMeasure->appendPoint(pos, TopLeft);
        }
        else if (type == BottomRight) {
            m_shapeList[m_shapeList.size() - 1]->appendPoint(pos, BottomRight);
            m_measureType = NoType;
        }
    }
    else if (m_measureType == AngleType) {
        if (type == FPoint) {
            MeasureBase* agMeasure = new MeasureBase(AngleType);
            m_shapeList.append(agMeasure);
            m_scene->addItem(agMeasure);
            agMeasure->appendPoint(pos, FPoint);
        }
        else if (type == AnglePoint) {
            m_shapeList[m_shapeList.size() - 1]->appendPoint(pos, AnglePoint);
        }
        else {
            m_shapeList[m_shapeList.size() - 1]->appendPoint(pos, EdgePoint);
            m_measureType = NoType;
        }
    }
    else if (m_measureType == PToLineType) {
        if (type == FPoint) {
            MeasureBase* pl = new MeasureBase(PToLineType);
            m_shapeList.append(pl);
            m_scene->addItem(pl);
            pl->appendPoint(pos, FPoint);
        }
        else if (type == EdgePoint) {
            m_shapeList[m_shapeList.size() - 1]->appendPoint(pos, EdgePoint);
        }
        else {
            m_shapeList[m_shapeList.size() - 1]->appendPoint(pos, PPoint);
            m_measureType = NoType;
        }
    }
}
void MeasureGraphView::returnDeletePosSlot(QPointF pos) {
    for (int i = 0; i < m_scene->items().size(); i++) {
        MeasureBase* item = (MeasureBase*)m_scene->items()[i];
        QPointF lt = item->getTopLeft();
        if (pos == lt) {
            qDebug() << "index: " << i;
            m_scene->removeItem(item);
            break;
        }
    }
    m_scene->update();
}

Scene代码:

GraphicsScene::GraphicsScene(QObject *parent)
	: QGraphicsScene(parent)
{
	m_enable = false;
	m_bll = BllData::getInstance();
	connect(m_bll, &BllData::setMeasureEnableSignal, this, &GraphicsScene::setMeasureEnableSlot);
}
GraphicsScene::~GraphicsScene()
{}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent* event) {
	if (m_enable) {
		m_clickCnt++;
		if (m_type == DistanceType) {
			if (m_clickCnt == 1) {
				m_bll->pressMeasurePos(event->scenePos(), TopLeft);
			}
			else if (m_clickCnt == 2) {
				m_enable = false;
				m_bll->pressMeasurePos(event->scenePos(), BottomRight);
			}
		}
		else if (m_type == AngleType) {
			if (m_clickCnt == 1) {
				m_bll->pressMeasurePos(event->scenePos(), FPoint);
			}
			else if (m_clickCnt == 2) {
				m_bll->pressMeasurePos(event->scenePos(), AnglePoint);
			}
			else if (m_clickCnt == 3) {
				m_enable = false;
				m_bll->pressMeasurePos(event->scenePos(), EdgePoint);
			}
		}
		else if (m_type == PToLineType) {
			if (m_clickCnt == 1) {
				m_bll->pressMeasurePos(event->scenePos(), FPoint);
			}
			else if (m_clickCnt == 2) {
				m_bll->pressMeasurePos(event->scenePos(), EdgePoint);
			}
			else if (m_clickCnt == 3) {
				m_enable = false;
				m_bll->pressMeasurePos(event->scenePos(), PPoint);
			}
		}
	}
	else {
		QGraphicsScene::mousePressEvent(event);
	}
}
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
	QGraphicsScene::mouseMoveEvent(event);
}
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) {
	QGraphicsScene::mouseReleaseEvent(event);
}
void GraphicsScene::setMeasureEnableSlot(MeasureType type) {
	m_type = type;
	m_enable = true;
	m_clickCnt = 0;
}

MeasureShape代码:

MeasureBase::MeasureBase(MeasureType type)
{
	m_type = type;
	m_deleteEnable = false;
	m_bll = BllData::getInstance();
	connect(m_bll, &BllData::deleteShapeEnableSignal, this, &MeasureBase::deleteShapeEnableSlot);
	m_pen_noSelected.setColor(QColor(0, 160, 230));
	m_pen_noSelected.setWidth(2);
	m_pen_isSelected.setColor(QColor(255, 0, 255));
	m_pen_isSelected.setWidth(2);
	this->setPen(m_pen_noSelected);
	this->setFlags(QGraphicsItem::ItemIsSelectable |
		QGraphicsItem::ItemIsMovable |
		QGraphicsItem::ItemIsFocusable);
}

MeasureBase::~MeasureBase()
{
}
QRectF MeasureBase::boundingRect() const {
	int w = abs(m_tl.x() - m_br.x());
	int h = abs(m_tl.y() - m_br.y());
	int x0 = m_tl.x() < m_br.x() ? m_tl.x() : m_br.x();
	int y0 = m_tl.y() < m_br.y() ? m_tl.y() : m_br.y();
	QPointF center(x0 + w / 2, y0 + h / 2);
	w = w > 100 ? w : 100;
	h = h > 50 ? h : 50;
	int xx0 = center.x() - w / 2;
	int yy0 = center.y() - h / 2;
	QRectF rect(xx0, yy0, w, h);
	return rect;
}
void MeasureBase::focusInEvent(QFocusEvent* event) {
	Q_UNUSED(event);
	this->setPen(m_pen_isSelected);
}
void MeasureBase::focusOutEvent(QFocusEvent* event) {
	Q_UNUSED(event);
	this->setPen(m_pen_noSelected);
}
void MeasureBase::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) {
	Q_UNUSED(option);
	Q_UNUSED(widget);
	painter->setPen(this->pen());
	painter->setBrush(this->brush());
	int w = abs(m_tl.x() - m_br.x());
	int h = abs(m_tl.y() - m_br.y());
	int x0 = m_tl.x() < m_br.x() ? m_tl.x() : m_br.x();
	int y0 = m_tl.y() < m_br.y() ? m_tl.y() : m_br.y();
	if (m_type == DistanceType) {
		double dis = sqrt(pow(m_tl.x() - m_br.x(), 2) + pow(m_tl.y() - m_br.y(), 2));
		//dis = qRound(dis * 100) * 0.01;
		painter->drawLine(m_tl, m_br);
		if (dis > 5) {
			painter->setPen(QPen(QColor(255, 64, 64)));
			QPointF center(x0 + w / 2, y0 + h / 2);
			QString disStr = QString::number((int)dis).append(" pix");
			painter->drawText(center, disStr);
		}
	}
	else if (m_type == AngleType) {
		if (m_list.size() == 3) {
			calAg();
			QLineF line1(m_list[0], m_list[1]);
			QLineF line2(m_list[1], m_list[2]);
			painter->drawLine(line1);
			painter->drawLine(line2);
			painter->setPen(QPen(Qt::darkRed, 2, Qt::SolidLine));
			QRectF rect(m_list[1].x() - 16, m_list[1].y() - 16, 32, 32);
			painter->drawPie(rect, m_ags * 16, m_agr * 16);
			QString strag = "";
			m_agr = qRound(m_agr * 100) * 0.01;
			strag.append(QString::number(abs(m_agr))).append("°");
			painter->drawText(m_center.x()- m_radius/3, m_center.y(), strag);
		}
	}
	else if (m_type == PToLineType) {
		if (m_list.size() == 3) {
			//qDebug() << "m_type == PToLineType  ----------";
			calData();
			QLineF line1(m_list[0], m_list[1]);
			QLineF line2(m_list[2], m_intersectionP);
			painter->drawLine(line1);
			painter->setPen(QPen(Qt::darkGreen, 2, Qt::DashLine));
			painter->drawLine(line2);
			painter->setPen(QPen(QBrush(QColor(255, 106, 106)), 2, Qt::SolidLine));
			QString strldis = "LDis: ";
			strldis.append(QString::number(m_disH)).append(" pix");
			painter->drawText(m_center.x() -m_radius+10, m_center.y() -m_radius/2, strldis);
			QString strlvdis = "LVDis: ";
			strlvdis.append(QString::number(m_disV)).append(" pix");
			painter->drawText(m_center.x() - m_radius+10, m_center.y() - m_radius / 2+20, strlvdis);
		}
	}
	this->update();
}
void MeasureBase::calData() {
	int x1 = m_list[0].x();
	int y1 = m_list[0].y();
	int x2 = m_list[1].x();
	int y2 = m_list[1].y();
	int x3 = m_list[2].x();
	int y3 = m_list[2].y();
	if (x2 - x1 != 0) {
		double k = (double)(y2 - y1) / (x2 - x1);
		if (k != 0) {
			double b = (double)(y1 - k * x1);
			double vk = -1 / k;
			double vb = (double)(y3 - vk * x3);
			double x = (vb - b) / (k - vk);
			double y = k * x + b;
			m_intersectionP.setX(x);
			m_intersectionP.setY(y);
		}
		else {
			qDebug() << "x1==x2";
			m_intersectionP.setX(x3);
			m_intersectionP.setY(y1);
		}
	}
	else {
		m_intersectionP.setX(x1);
		m_intersectionP.setY(y3);
	}
	double DD = (y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1);
	double D = sqrt(DD);
	m_disH = D;
	int x4 = m_intersectionP.x();
	int y4 = m_intersectionP.y();
	double ff = (y4 - y3) * (y4 - y3) + (x4 - x3) * (x4 - x3);
	double f = sqrt(ff);
	m_disV = f;
}
void MeasureBase::updatePosData(MeasureType type, QPointF org, QPointF pos) {
	//QList<QPointF> list;
	m_list.clear();
	for (int i = 0; i < m_pointList.size(); i++) {
		QPointF p = m_pointList[i]->getPoint();
		//qDebug() << " list index : " << i << " pos: " << p << " org: " << org;
		if ((abs(p.x() - org.x()) <= 2) && (abs(p.y() - org.y()) <= 2)) {
			//qDebug() << "find it------------------------";
			m_pointList[i]->setPoint(pos);
		}
		m_list.append(m_pointList[i]->getPoint());
	}
	m_center = getCentroid();
	getMaxLength();
	QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2);
	m_tl = QPointF(m_center.x() - m_radius, m_center.y() - m_radius);
	m_br = QPointF(m_center.x() + m_radius, m_center.y() + m_radius);
	this->update();
	
}
void MeasureBase::calAg() {
	QPointF p0 = m_list[1];
	QPointF p1 = m_list[0];
	QPointF p2 = m_list[2];
	QPoint p3(p0.x() + 100, p0.y());
	QPoint p0p1;
	p0p1.setX(p1.x() - p0.x());
	p0p1.setY(p0.y() - p1.y());
	QPoint p0p2;
	p0p2.setX(p2.x() - p0.x());
	p0p2.setY(p0.y() - p2.y());
	QPoint p0p3;
	p0p3.setX(p3.x() - p0.x());
	p0p3.setY(p0.y() - p3.y());
	double cosp1p2_1 = p0p1.x() * p0p2.x() + p0p1.y() * p0p2.y();
	double cosp1p2_2 = sqrt(p0p1.x() * p0p1.x() + p0p1.y() * p0p1.y()) * sqrt(p0p2.x() * p0p2.x() + p0p2.y() * p0p2.y());
	double  cosp1p2 = cosp1p2_1 / cosp1p2_2;
	double agp1p2 = abs(acos(cosp1p2)) * 180 / 3.1415926;
	double cosp2p3_1 = p0p2.x() * p0p3.x() + p0p2.y() * p0p3.y();
	double cosp2p3_2 = sqrt(p0p2.x() * p0p2.x() + p0p2.y() * p0p2.y()) * sqrt(p0p3.x() * p0p3.x() + p0p3.y() * p0p3.y());
	double  cosp2p3 = cosp2p3_1 / cosp2p3_2;
	double agp2p3 = abs(acos(cosp2p3)) * 180 / 3.1415926;
	double d = p0p2.x() * p0p1.y() - p0p1.x() * p0p2.y();
	if (p2.y() > p0.y()) {
		agp2p3 = -agp2p3;
	}
	if (d < 0) {
		agp1p2 = -agp1p2;
	}
	m_ags = agp2p3;
	m_agr = agp1p2;
	this->update();
}
void MeasureBase::mousePressEvent(QGraphicsSceneMouseEvent* event) {
	if (m_deleteEnable) {
		m_deleteEnable = false;
		m_bll->returnDeletePos(m_tl);
	}
}
void MeasureBase::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
	qreal dx = event->scenePos().x() - event->lastScenePos().x();
	qreal dy = event->scenePos().y() - event->lastScenePos().y();
	this->moveBy(dx, dy);
	this->update();
}
void MeasureBase::setTopLeft(QPointF pos) {
	m_tl = pos;
}
QPointF MeasureBase::getTopLeft() {
	return m_tl;
}
void MeasureBase::setBottomRight(QPointF pos) {
	m_br = pos;
}
QPointF MeasureBase::getBottomRight() {
	return m_br;
}
void MeasureBase::setDot(QPointF pos) {
	m_dot = pos;
}
QPointF MeasureBase::getDot() {
	return m_dot;
}
void MeasureBase::appendPoint(QPointF pos, PointType type) {
	if (m_type == DistanceType) {
		if (type == TopLeft) {
			setTopLeft(pos);
			setBottomRight(pos);
			PointBase* p1 = new PointBase(DistanceType, TopLeft, pos);
			p1->setParentItem(this);
			p1->setBrush(QBrush(QColor(0, 255, 0)));
			m_pointList.append(p1);
		}
		else if (type == BottomRight) {
			setBottomRight(pos);
			PointBase* p2 = new PointBase(DistanceType, BottomRight, pos);
			p2->setParentItem(this);
			p2->setBrush(QBrush(QColor(0, 255, 0)));
			m_pointList.append(p2);
			this->update();
		}
	}
	else if (m_type == AngleType) {
		if (type == FPoint) {
			m_list.append(pos);
			setTopLeft(pos);
			setBottomRight(pos);
			PointBase* p1 = new PointBase(AngleType, FPoint, pos);
			p1->setParentItem(this);
			p1->setBrush(QBrush(QColor(0, 255, 0)));
			m_pointList.append(p1);
		}
		else if (type == AnglePoint) {
			m_list.append(pos);
			m_center = getCentroid();
			getMaxLength();
			QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2);
			m_tl = QPointF(m_center.x() - m_radius, m_center.y() - m_radius);
			m_br = QPointF(m_center.x() + m_radius, m_center.y() + m_radius);
			PointBase* p = new PointBase(AngleType, AnglePoint,pos);
			p->setParentItem(this);
			p->setBrush(QBrush(QColor(255, 0, 0)));
			m_pointList.append(p);
		}
		else {
			m_list.append(pos);
			m_center = getCentroid();
			getMaxLength();
			QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2);
			m_tl = QPointF(m_center.x() - m_radius, m_center.y() - m_radius);
			m_br = QPointF(m_center.x() + m_radius, m_center.y() + m_radius);
			PointBase* p = new PointBase(AngleType, EdgePoint, pos);
			p->setParentItem(this);
			p->setBrush(QBrush(QColor(0, 255, 0)));
			m_pointList.append(p);
		}
	}
	else if (m_type == PToLineType) {
		if (type == FPoint) {
			m_list.append(pos);
			setTopLeft(pos);
			setBottomRight(pos);
			PointBase* p1 = new PointBase(PToLineType, FPoint, pos);
			p1->setParentItem(this);
			p1->setBrush(QBrush(QColor(0, 255, 0)));
			m_pointList.append(p1);
		}
		else if (type == EdgePoint) {
			m_list.append(pos);
			m_center = getCentroid();
			getMaxLength();
			QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2);
			m_tl = QPointF(m_center.x() - m_radius, m_center.y() - m_radius);
			m_br = QPointF(m_center.x() + m_radius, m_center.y() + m_radius);
			PointBase* p = new PointBase(PToLineType, EdgePoint, pos);
			p->setParentItem(this);
			p->setBrush(QBrush(QColor(0, 255, 0)));
			m_pointList.append(p);
		}
		else {
			m_list.append(pos);
			m_center = getCentroid();
			getMaxLength();
			QRectF(m_center.x() - m_radius, m_center.y() - m_radius, m_radius * 2, m_radius * 2);
			m_tl = QPointF(m_center.x() - m_radius, m_center.y() - m_radius);
			m_br = QPointF(m_center.x() + m_radius, m_center.y() + m_radius);
			PointBase* p = new PointBase(PToLineType, PPoint, pos);
			p->setParentItem(this);
			p->setBrush(QBrush(QColor(255, 0, 0)));
			m_pointList.append(p);
		}
	}
}
QPointF MeasureBase::getCentroid() {
	qreal x = 0;
	qreal y = 0;
	if (m_list.size() > 1) {
		for (int i = 0; i < m_list.size(); i++) {
			x += m_list[i].x();
			y += m_list[i].y();
		}
		x = x / m_list.size();
		y = y / m_list.size();
	}
	return QPointF(x, y);
}
void MeasureBase::getMaxLength() {
	QVector<qreal> vec;
	for (auto& temp : m_list)
	{
		qreal dis = sqrt(pow(m_center.x() - temp.x(), 2) + pow(m_center.y() - temp.y(), 2));
		vec.append(dis);
	}
	qreal ret = 0;
	for (auto& temp : vec)
	{
		if (temp > ret) {
			ret = temp;
		}
	}
	m_radius = ret;
}
void MeasureBase::deleteShapeEnableSlot() {
	m_deleteEnable = true;
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值