• 流程图拖拽视觉编程-流程编辑器


    目录

    一、简介

    二、流程编辑器-视图实现

    三、参考资料


    一、简介

    前期文章:

    流程图拖拽视觉编程--概述_Jason~shen的博客-CSDN博客

    本期内容:

    本期将介绍流程编辑器模块的实现方法,效果图如下所示。该模块基于QT Graphics/View实现,由视图、自定义图元、图元管理器组成。

    二、流程编辑器-视图实现

    视图的功能是提供一个节点显示窗口,支持缩放、平移和网格线背景。

    该部分继承QGraphicsView实现,定义接口如下:

    1. class GRAPHICSLIBSHARED_EXPORT BaseGraphicsView: public QGraphicsView
    2. {
    3. Q_OBJECT
    4. public:
    5. explicit BaseGraphicsView(QWidget *parent = nullptr);
    6. ~BaseGraphicsView();
    7. void setFactorMax(double val); //最大缩放因子
    8. void setFactorMin(double val); //最小缩放因子
    9. void setShowGrid(bool b); //是否显示网格线
    10. void setMoveSceneEnabled(bool b); //是否平移使能
    11. public slots:
    12. void zoomIn();
    13. void zoomOut();
    14. protected:
    15. void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
    16. void drawBackground(QPainter *painter, const QRectF &rect) Q_DECL_OVERRIDE;
    17. void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    18. void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    19. void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    20. private:
    21. void drawGrid(QPainter *painter, double gridStep);
    22. private:
    23. double m_factorMax;
    24. double m_factorMin;
    25. QPointF m_scenePos;
    26. QPointF m_pressPos;
    27. bool m_moveScene;
    28. bool m_showGrid;
    29. bool m_moveSceneEnabled;
    30. };

    缩放的实现:核心函数scale(), 配合鼠标事件操作,重写鼠标滚动事件函数wheelEvent,限制视图过大或者过小。

    1. void BaseGraphicsView::zoomIn()
    2. {
    3. setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    4. scale(1.2, 1.2);
    5. }
    6. void BaseGraphicsView::zoomOut()
    7. {
    8. setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    9. scale(1 / 1.2, 1 / 1.2);
    10. }
    11. void BaseGraphicsView::wheelEvent(QWheelEvent *event)
    12. {
    13. qreal factor_out = transform().scale(1.2, 1.2).mapRect(QRectF(0, 0, 1, 1)).width();
    14. qreal factor_in = transform().scale(1 / 1.2, 1 / 1.2).mapRect(QRectF(0, 0, 1, 1)).width();
    15. if (event->delta() > 0)
    16. {
    17. if(factor_out > m_factorMax)
    18. {
    19. return; /* 防止视图过大 */
    20. }
    21. zoomIn();
    22. }
    23. else
    24. {
    25. if(factor_in < m_factorMin)
    26. {
    27. return; /* 防止视图过小 */
    28. }
    29. zoomOut();
    30. }
    31. update();
    32. }

    平移的实现: 核心函数setSceneRect(),配合鼠标事件操作,重写鼠标按下mousePressEvent、移动mouseMoveEvent、释放mouseReleaseEvent事件函数。

    1. void BaseGraphicsView::mousePressEvent(QMouseEvent *event)
    2. {
    3. if(m_moveSceneEnabled)
    4. {
    5. QMouseEvent fake(event->type(), event->pos(), Qt::LeftButton, Qt::LeftButton, event->modifiers());
    6. m_scenePos = mapToScene(event->pos());
    7. m_pressPos = m_scenePos;
    8. setDragMode(QGraphicsView::NoDrag);
    9. if (QApplication::keyboardModifiers() == Qt::ControlModifier &&
    10. event->button() == Qt::LeftButton)
    11. {
    12. setDragMode(QGraphicsView::RubberBandDrag);
    13. }
    14. if (event->button() == Qt::MiddleButton)
    15. {
    16. setDragMode(QGraphicsView::ScrollHandDrag);
    17. setInteractive(false);
    18. event = &fake;
    19. m_moveScene = true;
    20. }
    21. update();
    22. }
    23. QGraphicsView::mousePressEvent(event);
    24. }
    25. void BaseGraphicsView::mouseMoveEvent(QMouseEvent *event)
    26. {
    27. if(m_moveSceneEnabled)
    28. {
    29. m_scenePos = mapToScene(event->pos());
    30. if (m_moveScene)
    31. {
    32. QPointF difference = m_pressPos - m_scenePos;
    33. setSceneRect(sceneRect().translated(difference.x(), difference.y()));
    34. }
    35. update();
    36. }
    37. QGraphicsView::mouseMoveEvent(event);
    38. }
    39. void BaseGraphicsView::mouseReleaseEvent(QMouseEvent *event)
    40. {
    41. if(m_moveSceneEnabled)
    42. {
    43. QMouseEvent fake(event->type(), event->pos(), Qt::LeftButton, Qt::LeftButton, event->modifiers());
    44. if (event->button() == Qt::MiddleButton)
    45. {
    46. setDragMode(QGraphicsView::NoDrag);
    47. setInteractive(true);
    48. event = &fake;
    49. }
    50. m_moveScene = false;
    51. update();
    52. }
    53. QGraphicsView::mouseReleaseEvent(event);
    54. }

    网格线背景,通过绘图类QPainter画线,重写绘制背景函数drawBackground

    1. void BaseGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
    2. {
    3. QGraphicsView::drawBackground(painter, rect);
    4. if(m_showGrid)
    5. {
    6. QPen pfine(QColor::fromRgb(50, 50, 50), 0.6);
    7. painter->setPen(pfine);
    8. drawGrid(painter, 15);
    9. QPen p(QColor::fromRgb(50, 50, 50), 2.0);
    10. painter->setPen(p);
    11. drawGrid(painter, 150);
    12. }
    13. }
    14. void BaseGraphicsView::drawGrid(QPainter *painter, double gridStep)
    15. {
    16. QRect windowRect = rect();
    17. QPointF tl = mapToScene(windowRect.topLeft());
    18. QPointF br = mapToScene(windowRect.bottomRight());
    19. double left = qFloor(tl.x() / gridStep - 0.5);
    20. double right = qFloor(br.x() / gridStep + 1.0);
    21. double bottom = qFloor(tl.y() / gridStep - 0.5);
    22. double top = qFloor(br.y() / gridStep + 1.0);
    23. for (int xi = int(left); xi <= int(right); ++xi)
    24. {
    25. QLineF line(xi * gridStep, bottom * gridStep,
    26. xi * gridStep, top * gridStep );
    27. painter->drawLine(line);
    28. }
    29. for (int yi = int(bottom); yi <= int(top); ++yi)
    30. {
    31. QLineF line(left * gridStep, yi * gridStep,
    32. right * gridStep, yi * gridStep );
    33. painter->drawLine(line);
    34. }
    35. }

    三、参考资料

    文章

    GitHub开源推荐 | 节点编辑器-技术圈

    python版本

    Pavel Křupala / pyqt-node-editor · GitLab

    https://blog.csdn.net/mahuatengmmp/category_9948511.html

    Release v0.3.1 · beyse/NodeEditor · GitHub

    qt4/qt5版本

    GitHub - Buanderie/qnodeseditor: Originally from http://algoholic.eu/qnodeseditor-qt-nodesports-based-data-processing-flow-editor/

    GitHub - hzt1234hf/FlowChartTools: 使用QT开发的跨平台(Windows、Linux)流程图绘制工具

  • 相关阅读:
    小程序--分包加载
    Flink SQL 在kerberos on yarn环境下提交
    人大加拿大女王金融硕士项目——追逐梦想,无论何时起步都不迟
    List集合
    2024 王道考研-数据结构(线性表_2)
    JAVA智慧校园平台系统源码:基于前后端框架VUE2+Spring boot+Wed端原生小程序搭建的智慧校园平台
    DHCP服务详解
    基于Spring Boot应用JdbcTemplate操作数据库(查增改删)
    【C#】WPF获取屏幕分辨率
    Tcl语言:基础入门(一)
  • 原文地址:https://blog.csdn.net/qq_40602000/article/details/130414389