QGraphicsView 实现 简单工作流

一、运行效果

执行删除

二、简单介绍

使用scene和vie来完成最终显示。

  // 创建 WorkflowScene 和视图
    m_scene = new WorkFolwScene();
    m_scene->setBackgroundBrush(Qt::black);
    m_view = new QGraphicsView(m_scene);
    m_view->setScene(m_scene);

绘制时当为空,只绘制矩形和文本。否则就绘制直线,三角形,矩形,文本。并且没绘制依次更新nextItemPos的位置。我这因为矩形宽100,三角形占据的水平位置差不多为10,所以每次给它加110就可以了,视觉效果还可以。

删除,当有两个以上,就倒着删除直线,三角形,矩形,文本。

三,代码

#ifndef WORKFOLWSCENE_H
#define WORKFOLWSCENE_H
#include<QGraphicsItem>
#include<QGraphicsScene>
#include<QWidget>
#include<QMouseEvent>
#include<QDebug>
#include<QRandomGenerator>
#include<QGraphicsSceneMouseEvent>
class WorkFolwScene : public QGraphicsScene
{
public:
    // WorkFolwScene();
    WorkFolwScene(QObject *parent = nullptr);
    void drawRectangle();
    void drawArrow();
    void clearLastDrawnItem();

private:
    QPointF nextItemPos; // 下一个图形的位置
};

#endif // WORKFOLWSCENE_H
#include "workfolwscene.h"

//WorkFolwScene::WorkFolwScene()
//{

//}

WorkFolwScene::WorkFolwScene(QObject *parent):QGraphicsScene(parent)
{
    nextItemPos.setX(0);
}

void WorkFolwScene::drawRectangle()
{
    qDebug()<<"drawRectangle";
      if (this->items().size()==0){
        nextItemPos.setX(0);
    }
    // 创建矩形图形项
    QGraphicsRectItem *rect = new QGraphicsRectItem(QRectF(nextItemPos.x(), nextItemPos.y(), 100, 50));
    rect->setBrush(Qt::blue); // 设置矩形的填充颜色
    addItem(rect);

    // 添加文本
    QGraphicsTextItem *textItem = new QGraphicsTextItem("Hello World!");
    int randomInt = QRandomGenerator::global()->bounded(10);
    textItem->setPlainText(QString::number(randomInt));
    QFont font("Arial", 10); // 设置字体和大小
    textItem->setFont(font);
    textItem->setDefaultTextColor(Qt::white); // 设置文本颜色
    QPointF textPos = QPointF(nextItemPos.x() + 10, nextItemPos.y() + 10); // 文本位置偏移量
    textItem->setPos(textPos);
    addItem(textItem);

    // 更新下一个图形的位置
    nextItemPos.setX(nextItemPos.x() + 110); // 假设间隔为 101
}

void WorkFolwScene::drawArrow()
{
    qDebug()<<"drawRectangle";
    qreal arrowSize = 10; // 箭头大小
    qreal offsetY = 25; // 向下偏移量

    // 创建箭头的线段,向下偏移25个单位
    QGraphicsLineItem *line = new QGraphicsLineItem(QLineF(nextItemPos.x(), nextItemPos.y()+offsetY,
                                                           nextItemPos.x() + 100, nextItemPos.y() + offsetY));
    line->setPen(QPen(Qt::white)); // 设置箭头线段的颜色和样式
    addItem(line);

    // 创建箭头头部的三角形,向下偏移25个单位
    QPolygonF arrowHead;
    arrowHead << QPointF(0, 0) << QPointF(-arrowSize, arrowSize/2) << QPointF(-arrowSize, -arrowSize/2);
    QGraphicsPolygonItem *arrow = new QGraphicsPolygonItem(arrowHead);
    arrow->setBrush(Qt::white); // 设置箭头头部的颜色
    arrow->setPen(QPen(Qt::white)); // 设置箭头头部的边框颜色和样式
    arrow->setPos(nextItemPos.x() + 100, nextItemPos.y() + offsetY); // 设置箭头头部的位置
    addItem(arrow);

    // 更新下一个图形的位置
    nextItemPos.setX(nextItemPos.x() + 110); // 假设间隔为 110

}

void WorkFolwScene::clearLastDrawnItem()
{
   QList<QGraphicsItem *> itemsList = items(Qt::AscendingOrder); // 获取场景中所有的图形项

       // 如果场景中没有图形项,则重置 nextItemPos 并直接返回
       if (itemsList.isEmpty()) {
           nextItemPos.setX(0);
           this->clear();
           return;
       }

       // 定义要删除的图形项类型列表,按照绘制顺序从后往前删除
       QList<int> typesToDelete = {
           QGraphicsTextItem::Type,
           QGraphicsRectItem::Type,
           QGraphicsPolygonItem::Type,
           QGraphicsLineItem::Type
       };

       // 从后往前遍历要删除的类型
       for (int type : typesToDelete) {
           // 找到符合当前类型的最后绘制的图形项
           for (int i = itemsList.size() - 1; i >= 0; --i) {
               QGraphicsItem *item = itemsList[i];
               if (item->type() == type) {
                   removeItem(item);
                   delete item;
                   itemsList.removeAt(i); // 从列表中移除已删除的项
                   break; // 删除一个后退出循环
               }
           }
       }
}




#include "widget.h"
#include<QHBoxLayout>
#include<QPushButton>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //主界面布局
    QVBoxLayout *layout = new QVBoxLayout(this);
    //创建 WorkflowScene 的widget
    //    QWidget *wfWidget=new QWidget();
    //    wfWidget->setStyleSheet("border:1px solid black");
    QHBoxLayout *hb1=new QHBoxLayout();


    // 创建 WorkflowScene 和视图
    m_scene = new WorkFolwScene();
    m_scene->setBackgroundBrush(Qt::black);
    m_view = new QGraphicsView(m_scene);
    m_view->setScene(m_scene);
    // 添加到布局

    hb1->addWidget(m_view);
    QHBoxLayout *hb2=new QHBoxLayout();
    // 创建按钮并添加到布局
    QPushButton *button = new QPushButton("绘制", this);
    QPushButton *clearBtn = new QPushButton("清除", this);
    connect(button, &QPushButton::clicked, this, &Widget::onDrawClicked);
    connect(clearBtn,&QPushButton::clicked, this, &Widget::onClearClicked);
    hb2->addWidget(button);
    hb2->addWidget(clearBtn);
    hb2->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding));


    layout->addLayout(hb1);
    layout->addLayout(hb2);
    this->setLayout(layout);
    this->resize(800,750);
}

Widget::~Widget()
{
}

void Widget::onDrawClicked()
{
    if(m_scene->items().isEmpty())
    {
        m_scene->clear();
        m_view->resetTransform();
        m_view->centerOn(0,0);
        m_scene->drawRectangle();
    }else {

        m_scene->drawArrow();
        m_scene->drawRectangle();
    }

}

void Widget::onClearClicked()
{
     m_scene->clearLastDrawnItem();
}

全部评论
大佬在那里高就
点赞 回复 分享
发布于 08-06 12:13 广东

相关推荐

10-25 12:05
已编辑
湖南科技大学 Java
若梦难了:我有你这简历,已经大厂乱杀了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务