图形/视图结构的三个坐标系

图形/视图结构的三个坐标系分别为视图结构系=物理结构系,场景坐标系,图形项坐标系。
本文记录实践三个坐标系及视图与场景坐标转换,通过事件槽来显示出来的过程。

  1. 自定义1个View视图组件,其中扩展了鼠标点击、鼠标移动的事件,在这两个事件中分别发送/广播了信号 鼠标按下左键、鼠标移动的信号
  2. 在主窗体中,使用该自定义的视图组件,
  3. 定义1个矩形框,然后将矩形框设置为场景
  4. 在该场景中添加1个蓝色椭圆图形项,1个红色圆的图形项
  5. 通过槽函数展示

在主窗体中,接收自定义组件发出的鼠标移动、鼠标点击左键的信号,在主窗体实现的槽函数中展示鼠标移动时,物理坐标(视图坐标)、场景坐标、图形项的坐标

自定义扩展GraphicsView组件

主界面设计

View组件提升为TGraphicsView

定义矩形区域,设置为场景

 

    //1. 创建一个区域 从 -200,-100开始,长400宽200
    QRectF rect(-200,-100,400,200);
    //2. 在这个位置上创建一个场景
    scene= new QGraphicsScene(rect,this);
    //3.给视图设置场景
    ui->view->setScene(scene);

画出该矩形-场景中添加矩形

可选,可选中

    //4.1添加一个矩形框
    QGraphicsRectItem *item = new QGraphicsRectItem(rect);
    //可选中的,可获取焦点
    item->setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsFocusable);
    //给item设置画笔
    QPen pen;
    pen.setWidth(2);
    item->setPen(pen);
    scene->addItem(item);//默认坐标 在scene的 0,0

 场景中添加椭圆

可移动、可选中、可获取焦点

    //4.2矩形框内创建一个椭圆,左上角坐标 -100,-50, 宽200 高100
    QGraphicsEllipseItem *eItem = new QGraphicsEllipseItem(-100,-50,200,100);
    eItem->setPos(0,0);//图形项在场景中的坐标
    eItem->setBrush(QBrush(Qt::blue));
    eItem->setFlags(QGraphicsItem::ItemIsMovable
                    |QGraphicsItem::ItemIsSelectable
                    |QGraphicsItem::ItemIsFocusable);
    scene->addItem(eItem);

 场景中添加圆

    //4.3矩形框内创建一个椭圆,左上角坐标 -100,-50, 宽100 高100  变成一个圆 填充红色
    QGraphicsEllipseItem *rItem = new QGraphicsEllipseItem(-50,-50,100,100);
    //设置到矩形框的右下角
    rItem->setPos(rect.right(),rect.bottom());        //图形项在场景中的坐标
    rItem->setBrush(QBrush(Qt::red));
    rItem->setFlags(QGraphicsItem::ItemIsMovable
                    |QGraphicsItem::ItemIsSelectable
                    |QGraphicsItem::ItemIsFocusable);
    scene->addItem(rItem);

场景清除选中

 scene->clearSelection();

鼠标十字星,开启鼠标跟踪、视图内组件拖曳模式

    ui->view->setCursor(Qt::CrossCursor);//设置十字光标
    ui->view->setMouseTracking(true);//设置鼠标跟踪后,才能获取到mouseMoveEvent
    ui->view->setDragMode(QGraphicsView::RubberBandDrag);//矩形选择框

绑定信号处理的槽

    connect(ui->view,SIGNAL(mouseMovePoint(QPoint)),this,SLOT(do_mouserMoveEvent(QPoint)));
    connect(ui->view,SIGNAL(mouseClicked(QPoint)),this,SLOT(do_mouseClicked(QPoint)));

鼠标移动执行槽

void GraphicsViewWindow::do_mouserMoveEvent(QPoint point)
{//传入的point 是 GraphicsView的坐标,物理坐标
    qDebug()<<"do_mouserMoveEvent...";
    labViewCord->setText(QString::asprintf("View坐标:%d,%d",point.x(),point.y()));
    QPointF pointScene =ui->view->mapToScene(point);//转换到Scene坐标
    labSceneCord->setText(QString::asprintf("Scene坐标:%0.f,%0.f",pointScene.x(),pointScene.y()));
}

鼠标点击执行槽

void GraphicsViewWindow::do_mouseClicked(QPoint point)
{//点击图形项的时候,显示Scene坐标,item坐标
    QPointF pointScene = ui->view->mapToScene(point);
    QGraphicsItem *item =NULL;
    item = scene->itemAt(pointScene,ui->view->transform());//获取光标下的绘图项
    if(item!=NULL)
    {
        QPointF pointItem = item->mapFromScene(pointScene);//转换为绘图
        labItemCord->setText(QString::asprintf("Item坐标:%.0f,%.0f",pointItem.x(),pointItem.y()));
    }
}

主窗体大小变化事件

窗口大小变化时,视图的sceneRect矩形的坐标始终未发生变化

void GraphicsViewWindow::resizeEvent(QResizeEvent *event)
{
    QString str = QString::asprintf("GraphicsView坐标,左上角是(0,0),宽度=%d,高度=%d",
                                    ui->view->width(),
                                    ui->view->height());
    ui->labViewSize->setText(str);
    QRectF rectF = ui->view->sceneRect();
    QString strScene = QString::asprintf("GraphicsView::sceneRect(Left,Top,Width,Height)=(%0.f,%0.f,%0.f,%0.f)",
                                         rectF.left(),
                                         rectF.top(),
                                         rectF.width(),
                                         rectF.height());
    ui->labSceneRect->setText(strScene);

    event->accept();
}

结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

castlooo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值