公司动态
使用QGraphicsView,QGraphicsScene,QGraphicsItem创建简单的流程图
非AI生成觉得有用就请您帮忙点赞转发收藏吧您的鼓励是我创作的动力多谢看官。目录一、流程图的基本图元二、核心思路三、流程图核心代码四、运行效果五、关键点总结六、可扩展方向七、参考链接一、流程图的基本图元包含矩形框、条件框和带箭头的直线二、核心思路使用 QGraphicsScene管理图元自定义节点QGraphicsRectItem自定义箭头QGraphicsLineItem在 paint()中绘制箭头头部使用 itemChange()实现拖动时箭头跟随三、流程图核心代码#include QApplication #include QGraphicsView #include QGraphicsScene #include QGraphicsRectItem #include QGraphicsLineItem #include QPainter #include cmath // 箭头 class ArrowItem : public QGraphicsLineItem { public: ArrowItem(QGraphicsItem *start, QGraphicsItem *end, QGraphicsItem *parent nullptr) : QGraphicsLineItem(parent), m_start(start), m_end(end) { setPen(QPen(Qt::black, 2)); updatePosition(); } void updatePosition() { if (!m_start || !m_end) return; QPointF p1 m_start-mapToScene(0, 0); QPointF p2 m_end-mapToScene(0, 0); setLine(QLineF(p1, p2)); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override { QLineF line this-line(); painter-setPen(pen()); painter-setBrush(Qt::black); painter-drawLine(line); const double arrowSize 10; const double angle std::atan2(-line.dy(), line.dx()); QPointF p1 line.p2() - QPointF( std::sin(angle M_PI / 6) * arrowSize, std::cos(angle M_PI / 6) * arrowSize ); QPointF p2 line.p2() - QPointF( std::sin(angle - M_PI / 6) * arrowSize, std::cos(angle - M_PI / 6) * arrowSize ); QPolygonF arrowHead; arrowHead line.p2() p1 p2; painter-drawPolygon(arrowHead); } private: QGraphicsItem *m_start, *m_end; }; // 流程节点 class FlowNode : public QGraphicsRectItem { public: FlowNode(const QString text, QGraphicsItem *parent nullptr) : QGraphicsRectItem(-40, -20, 80, 40, parent) { setBrush(Qt::lightGray); setFlag(ItemIsMovable); setFlag(ItemIsSelectable); setFlag(ItemSendsScenePositionChanges); m_text text; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) override { painter-setPen(Qt::black); painter-setBrush(brush()); painter-drawRect(rect()); painter-drawText(rect(), Qt::AlignCenter, m_text); } QVariant itemChange(GraphicsItemChange change, const QVariant value) override { if (change ItemPositionHasChanged) { for (ArrowItem *arrow : m_arrows) arrow-updatePosition(); } return QGraphicsRectItem::itemChange(change, value); } void addArrow(ArrowItem *arrow) { m_arrows.append(arrow); } private: QString m_text; QListArrowItem * m_arrows; };四、运行效果运行效果两个可拖动节点一条直线箭头连接拖动任一节点箭头实时跟随箭头头部始终朝向目标节点五、关键点总结QGraphicsScene容器管理所有图元QGraphicsRectItem矩形节点QGraphicsLineItem箭头主体paint()自定义绘制文本和箭头itemChange()实现拖动联动mapToScene()坐标转换关键六、可扩展方向性能优化渲染优化/绘制项优化/场景更新策略等对齐与框选工具撤销和重做功能导入导出功能折线 / 直角连线右键菜单删除 / 编辑保存到 JSON / 重新加载七、参考链接别再只会用QGraphicsView显示图片了手把手教你用它做个简易的流程图编辑器Qt 6.5实战