在控件graphicsView中实现绘图功能(二)

前言:

对于上一节没有完成的功能进行续写,对ui界面进行简单的修改,添加了椭圆绘制,绘制图形保存在graphicsView中这两个功能,后续会对文字添加,清屏以及图片旋转功能进行添加。

基础夯实:

1.创建 QGraphicsScene 和 QGraphicsView

在你的主窗口或者相应的QWidget中,创建一个 QGraphicsScene 和一个 QGraphicsView。QGraphicsScene 是图形的容器,而 QGraphicsView 用于显示这个场景。

#include <QGraphicsScene>  
#include <QGraphicsView>  
#include <QGraphicsEllipseItem>  
QGraphicsScene *scene = new QGraphicsScene(this);  
QGraphicsView *view = new QGraphicsView(scene, this);  
setCentralWidget(view); // 假设你在一个QMainWindow中

2. 在 QGraphicsScene 中添加椭圆

使用 QGraphicsEllipseItem 创建一个椭圆,并将其添加到 QGraphicsScene 中。你可以指定椭圆的矩形边界(使用 QRectF),或者简单地使用 x, y, width, height 参数。

QGraphicsEllipseItem *ellipse = scene->addEllipse(QRectF(10, 10, 100, 50), QPen(Qt::black), QBrush(Qt::blue));  
// 或者  
// QGraphicsEllipseItem *ellipse = scene->addEllipse(10, 10, 100, 50);  
// 然后你可以设置它的笔和刷  
// ellipse->setPen(QPen(Qt::black));  
// ellipse->setBrush(QBrush(Qt::blue));

3. 渲染和显示

将 QGraphicsView 添加到你的窗口或布局中后,它就会自动显示 QGraphicsScene 中的所有图形项,包括你刚刚添加的椭圆。

4. 推荐学习本文之前查看的链接:

在控件graphicsView中实现绘图功能(一)

效果展示:

在这里插入图片描述

实现功能:

实现了添加了椭圆绘制,绘制图形保存的graphicsView中这两个功能。

遇到问题:

一种图形只能添加一次,不能连续添加。图片无法保存到视图中。

核心代码:

//CustomGraphicsView.cpp
#include "CustomGraphicsView.h"
#include <QGraphicsRectItem>
#include <QGraphicsScene>
#include <QMouseEvent>

CustomGraphicsView::CustomGraphicsView(QWidget *parent)
    : QGraphicsView(parent)
{
}

void CustomGraphicsView::setDrawMode(DrawMode mode)
{
    currentDrawMode = mode;
}

// 辅助函数,用于创建新的椭圆项
QGraphicsEllipseItem* CustomGraphicsView::createEllipseItem(const QRectF &rect, const QPen &pen, const QBrush &brush)
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(rect);
    item->setPen(pen);
    item->setBrush(brush);
    scene()->addItem(item);
    ellipseItems.append(item);
    return item;
}


void CustomGraphicsView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        isDrawing = true;
        startPoint = mapToScene(event->pos());

        switch (currentDrawMode) {
        case RectMode:
            // 矩形模式下,初始化矩形的两个角(实际上是同一个点,稍后在move事件中更新)
            rectItem = new QGraphicsRectItem(QRectF(startPoint, QSizeF(0, 0)));
            rectItem->setPen(QPen(Qt::blue)); // 示例颜色
            scene()->addItem(rectItem);
            break;

        case LineMode:
            // 线条模式下,不立即绘制线条,只在move事件中根据起点和当前点绘制
            lineItem = nullptr; // 如果之前有线条,则忽略它(或根据需要重置)
            break;

        case EllipseMode:
            if (!ellipseItem) {
                QRectF ellipseRect(startPoint, QSizeF(0, 0)); // 初始大小为0,稍后在move事件中更新
                ellipseItem = createEllipseItem(ellipseRect, QPen(Qt::green), QBrush(Qt::NoBrush));
            }
            // 否则,不创建新项,只更新startPoint
            break;

        default:
            // ...
            break;
        }

        emit mouseClicked(event->pos());
    }

    QGraphicsView::mousePressEvent(event);
}

void CustomGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (isDrawing) {
        QPointF endPoint = mapToScene(event->pos());

        switch (currentDrawMode) {
        case RectMode:
        {
            QPointF topLeft = QPointF(qMin(startPoint.x(), endPoint.x()), qMin(startPoint.y(), endPoint.y()));
            QPointF bottomRight = QPointF(qMax(startPoint.x(), endPoint.x()), qMax(startPoint.y(), endPoint.y()));
            rectItem->setRect(QRectF(topLeft, bottomRight));
            break;
        }

        case LineMode:
        {
            if (!lineItem) {
                lineItem = scene()->addLine(startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y(), QPen(Qt::red));
            } else {
                lineItem->setLine(QLineF(startPoint, endPoint));
            }
            break;
        }

        case EllipseMode:
        {
            QPointF topLeft = QPointF(qMin(startPoint.x(), endPoint.x()), qMin(startPoint.y(), endPoint.y()));
            QPointF bottomRight = QPointF(qMax(startPoint.x(), endPoint.x()), qMax(startPoint.y(), endPoint.y()));
            QRectF ellipseRect(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y()));
            if (ellipseItem) {
                ellipseItem->setRect(ellipseRect);
            }
            break;
        }

        default:
            // 处理默认情况
            break;
        }
    }
    emit mouseMoved(event->pos());
}

void CustomGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton && isDrawing) {
        isDrawing = false;
    }

        emit mouseReleased(event->pos());
        //重置模型项,以便下一次重写
        switch (currentDrawMode) {
        case RectMode:
            rectItem = nullptr;
            break;

        case LineMode:
            lineItem = nullptr;
            break;

        case EllipseMode:
            ellipseItem = nullptr;
            break;
    }

    QGraphicsView::mouseReleaseEvent(event);
}

仓库源码:

代码在之前的链接中进行详细展示了,这里把源码放仓库了,欢迎二次开发:
https://gitee.com/wangning719/drawing

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值