Qt (高仿Visio)流程图组件开发(六) 流程图 线图元 如何绘制曲线 连接线移除视口后无法显示

本文详细介绍了Qt中高仿Visio流程图组件开发中的线图元实现,包括起始点计算、曲线绘制、箭头绘制,以及遇到的动态中点计算、曲线生效范围和移出视口后显示问题的解决方案。


本系列目录

Qt (高仿Visio)流程图组件开发(一) 效果展示及基本开发框架构思
Qt (高仿Visio)流程图组件开发(二) 基本图元绘制 图元间连线绘制
Qt (高仿Visio)流程图组件开发(三) 图元基类如何定义,流程图多种图元类型实现
Qt (高仿Visio)流程图组件开发(四) 流程图 图元对齐 磁吸线功能
Qt (高仿Visio)流程图组件开发(五) 流程图 双击编辑图元内容实现
Qt (高仿Visio)流程图组件开发(六) 流程图 线图元 如何绘制曲线 连接线移除视口后无法显示
Qt (高仿Visio)流程图组件开发(七) 流程图 简单操作界面搭建
Qt (高仿Visio)流程图组件开发(八) 流程图 鼠标拖动图元到场景(QGraphicsScene)创建
Qt (高仿Visio)流程图组件开发(九) 流程图 代码展示


前言

  本文主要讲解流程图当中的线图元,线图元在流程图中主要起到一个连接的作用,可以表示流程进行的方向,也可以用作判断图元的不同结果,如果想优化线图元功能可以参考下文。只是经验分享,描述内容并不绝对,如有误差欢迎指正。


一、线图元实现

1、基本实现思路

  连线首先需要找到起始点,所以线图元在构造时我们选择将起始图元传入,通过图元实时获取连线起始点。
  线图元类声明。

class FlowcharGraphicsLink 
	: public QObject
	, public QGraphicsPathItem
	, public FlowchartGraphicsItem
{
   
   
	Q_OBJECT


public:
	// 自循环只需要开始图元
	FlowcharGraphicsLink(FlowchartGraphicsItem* _start_item, FlowchartGraphicsItem* _end_item = nullptr, FlowcharGraphicsLinkInfo* _infor = new FlowcharGraphicsLinkInfo(), QObject *parent = nullptr);
	~FlowcharGraphicsLink();
}

  获取起始点。

// ! [1] 获取起始点
	switch (CompareDrawPoint(start_item_->GetCenterPoint(), end_item_->GetCenterPoint()))
	{
   
   
	case DrawLineAlignment::DrawLeft:
		start_point_ = start_item_->GetLeftPoint();
		end_point_ = end_item_->GetRightPoint();
		break;
	case DrawLineAlignment::DrawRight:
		start_point_ = start_item_->GetRightPoint();
		end_point_ = end_item_->GetLeftPoint();
		break;
	case DrawLineAlignment::DrawTop:
		start_point_ = start_item_->GetTopPoint();
		end_point_ = end_item_->GetBottomPoint();
		break;
	case DrawLineAlignment::DrawBottom:
		start_point_ = start_item_->GetBottomPoint();
		end_point_ = end_item_->GetTopPoint();
		break;
	default:
		break;
	}

2、起始点位置计算

  在两图元之间进行连线时,需要从图元边缘部分进行连线,这里的图元类提供上中,下中,左中,右中,中位置五个接口,通过这五个接口可以简单实现上述功能。

// ! [1] 获取起始点
	switch (CompareDrawPoint(start_item_->GetCenterPoint(), end_item_->GetCenterPoint()))
	{
   
   
	case DrawLineAlignment::DrawLeft:
		start_point_ = start_item_->GetLeftPoint();
		end_point_ = end_item_->GetRightPoint();
		break;
	case DrawLineAlignment::DrawRight:
		start_point_ = start_item_->GetRightPoint();
		end_point_ = end_item_->GetLeftPoint();
		break;
	case DrawLineAlignment::DrawTop:
		start_point_ = start_item_->GetTopPoint();
		end_point_ = end_item_->GetBottomPoint();
		break;
	case DrawLineAlignment::DrawBottom:
		start_point_ = start_item_->GetBottomPoint();
		end_point_ = end_item_->GetTopPoint();
		break;
	default:
		break;
	}

// 判断箭头连线起始点类型
DrawLineAlignment FlowcharGraphicsLink::CompareDrawPoint(QPointF _start_point, QPointF _end_point)
{
   
   
	// 直线斜率
	double k_num = (double)(_end_point.y() - _start_point.y()) / (_end_point.x() - _start_point.x());
	if (k_num >= -1 && k_num <= 1)
	{
   
   
		if (_start_point.x() >= _end_point.x())
		{
   
   
			return DrawLineAlignment::DrawLeft;
		}
		else
		{
   
   
			return DrawLineAlignment::DrawRight;
		}
	}
	else
	{
   
   
		if (_start_point.y() >= _end_point.y())
		{
   
   
			return DrawLineAlignment::DrawTop;
		}
		else
		{
   
   
			return DrawLineAlignment::DrawBottom;
		}
	}
}

3、箭头绘制

  流程图使用带有指向性的箭头作为连线,以此显示父子关系,所以线图元类(FlowcharGraphicsLink)需要继承(QGraphicsPathItem)来绘制不规则图形。箭头计算过程如下:

// ! [3] 获取箭头
	QPointF arrow_start_point = QPointF(curve_points[curve_points.size() - 2].first, curve_points[curve_points.size() - 2].second);
	QPointF arrow_end_point = QPointF(curve_points[curve_points.size() - 1].first, curve_points[curve_points.size() - 1].second);
	last_line_.setPoints(arrow_start_point, arrow_end_point);
	qreal arrowSize = 16;
	double angle = std::atan2(-last_line_.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦醒梦起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值