Qt绘图与图形视图之基本图元绘制的简单介绍

往期回顾

Qt绘图与图形视图之常见图形、路径、文字、图片的绘制介绍-CSDN博客

Qt绘图与图形视图之移动鼠标手动绘制任意多边形的简单介绍-CSDN博客

Qt绘图与图形视图之场景、视图架构的简单介绍-CSDN博客

 Qt绘图与图形视图之基本图元绘制的简单介绍

一、最终效果

可以对椭圆、圆这两个图元进行选择拖动,矩形图元设置了不可拖动,同时不管鼠标在哪都会实时显示其视图坐标、场景坐标,如果在某个图元上,还会显示其图元坐标

二、具体实现

 1、基本概念

最最基本的先区分好,三个坐标:

1、图元坐标是每个图元的中心点
2、视图原点坐标是基于QGraphicsView的起始点(0,0),也就是白色矩形区域的左上角
3、场景原点坐标是基于QGraphicsScene的,也就是图中黑色矩形框的中心点

2、设计思路

两个类,MyGraphicsView类继承自QGraphicsView,负责在图形视图中处理鼠标事件,而Widget类则负责场景、图元的创建和移动逻辑。

三、MyGraphicsView类

MyGraphicsView类继承自QGraphicsView,负责在图形视图中处理鼠标事件

1、构造函数里初始化

构造函数里初始化,设置鼠标形状、鼠标跟踪、鼠标拖拽模式

MyGraphicsView::MyGraphicsView(QWidget* parent)
    :QGraphicsView(parent)
{
    this->setCursor(Qt::CrossCursor); //设置鼠标形状为CrossCursor,十字光标型
    //设置鼠标跟踪
    //即使没有按下鼠标键,也能捕获鼠标移动事件
    this->setMouseTracking(true);
    //设置了拖拽模式为 RubberBandDrag,即可以通过鼠标拖拽创建一个橡皮筋选框
    this->setDragMode(QGraphicsView::RubberBandDrag);
}

2、鼠标形状设置

3、重写鼠标移动事件和按下事件

重写鼠标移动事件和按下事件,主要是捕获鼠标按下点的位置信息和移动点的位置信息,及时发送给界面进行处理

void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    //鼠标移动事件
    //当鼠标移动时,获取当前鼠标位置
    //event->pos()是鼠标相对于QGraphicsView的相对位置
    QPoint point=event->pos();  //QGraphicsView的坐标
    //将鼠标点击位置信息传递出去
    emit mouseMovePoint(point); //释放信号
    //继续处理鼠标移动事件
    QGraphicsView::mouseMoveEvent(event);
}
void MyGraphicsView::mousePressEvent(QMouseEvent *event)
{
    //鼠标左键按下事件,把这个点发送到界面上去
    if (event->button()==Qt::LeftButton)
    {
        QPoint point=event->pos();  //QGraphicsView的坐标
        emit mouseClicked(point); //释放信号
    }

    QGraphicsView::mousePressEvent(event);
}

四、Widget类

Widget类则负责场景、图元的创建和移动逻辑 

1、构造函数里链接两个信号并初始化QGraphicsView

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //链接两个信号
    QObject::connect(ui->graphicView, &MyGraphicsView::mouseMovePoint, this, &Widget::on_mouseMovePoint);
    QObject::connect(ui->graphicView,&MyGraphicsView::mouseClicked, this, &Widget::on_mouseClicked);

    //初始化QGraphicsView
    initGraphicsView();
}

2、初始化QGraphicsView函数

在初始化QGraphicsView函数里,主要是给视图设置场景,并创建图元

void Widget::initGraphicsView()
{
    QRectF   rect(-200,-100,400,200); //起始点x,y,矩形长,矩形宽
    scene = new QGraphicsScene(rect);   //创建一个场景对象

    //给视图设置场景
    ui->graphicView->setScene(scene); 

    //画一个矩形框,大小等于scene
    QGraphicsRectItem *item = new QGraphicsRectItem(rect);  

    //下面设置三个图元,没有指定父对象,那么其父对象就是场景
    //可选,可以有焦点,但是不能移动
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
    QPen    pen; 
    pen.setWidth(20);
    item->setPen(pen);
    scene->addItem(item); 

    //一个位于scene中心的椭圆
    QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100,-50,200,100); 
    item2->setPos(-200,0);
    item2->setBrush(QBrush(Qt::blue));
    //设置可移动,可选择,有焦点
    item2->setFlags(QGraphicsItem::ItemIsMovable 
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);
    scene->addItem(item2);

    //一个圆,中心位于scene的边缘
    QGraphicsEllipseItem  *item3=new QGraphicsEllipseItem(-50,-50,100,100); 
    item3->setPos(rect.right(),rect.bottom());
    item3->setBrush(QBrush(Qt::red));
    //设置可移动,可选择,有焦点
    item3->setFlags(QGraphicsItem::ItemIsMovable
                   | QGraphicsItem::ItemIsSelectable
                   | QGraphicsItem::ItemIsFocusable);
    scene->addItem(item3);

    //最开始清空选择
    scene->clearSelection();
}

3、常用图元 

QGraphicsEllipseItem          椭圆图元
QGraphicsLineItem              线段图元
QGraphicsPathItem            路径图元
QGraphicsPixmapItem        图片图元
QGraphicsPolygonItem      闭合图元
QGraphicsRectItem            矩形图元
QGraphicsSimpleTextItem  文字图元
QGraphicsTextItem              文字图元

4、对鼠标移动和点击事件做实现

对鼠标移动和点击事件做实现,主要是把拿到的点信息本身是GraphicsView的,而我们需要及时展现视图、场景、图元三个的坐标 

由于拿到的坐标本身就是基于GraphicsView的,所以可以直接显示视图坐标,然后通过mapToScene()转换到场景坐标并显示

void Widget::on_mouseMovePoint(QPoint point)
{
    //鼠标移动事件,point是 GraphicsView的坐标,物理坐标
    ui->label_viewpos->setText(QString::asprintf("%d,%d",point.x(), point.y()));
    QPointF pointScene=ui->graphicView->mapToScene(point); //转换到Scene坐标
    ui->label_scenepos->setText(QString::asprintf("%.0f,%.0f", pointScene.x(),pointScene.y()));
}

还是先转换为场景坐标,由于会创建多个图元,而我们每次显示的图元坐标都是基于鼠标当前所在的图元,所以我们需要先判断鼠标在哪个图元,是否在图元里,如果在,再转换为局部坐标并显示:

void Widget::on_mouseClicked(QPoint point)
{
    //鼠标单击事件
    QPointF pointScene=ui->graphicView->mapToScene(point); //转换到Scene坐标
    QGraphicsItem  *item=NULL;
    item=scene->itemAt(pointScene,ui->graphicView->transform()); //获取光标下的绘图项
    if (item != NULL) //有绘图项
    {
        QPointF pointItem=item->mapFromScene(pointScene); //转换为绘图项的局部坐标
        ui->label_itempos->setText(QString::asprintf("%.0f,%.0f", pointItem.x(),pointItem.y()));
    }
}

以上就是Qt里基本图元绘制的简单介绍。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

  • 32
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值