图形/视图结构的三个坐标系分别为视图结构系=物理结构系,场景坐标系,图形项坐标系。
本文记录实践三个坐标系及视图与场景坐标转换,通过事件槽来显示出来的过程。
- 自定义1个View视图组件,其中扩展了鼠标点击、鼠标移动的事件,在这两个事件中分别发送/广播了信号 鼠标按下左键、鼠标移动的信号
- 在主窗体中,使用该自定义的视图组件,
- 定义1个矩形框,然后将矩形框设置为场景
- 在该场景中添加1个蓝色椭圆图形项,1个红色圆的图形项
- 通过槽函数展示
在主窗体中,接收自定义组件发出的鼠标移动、鼠标点击左键的信号,在主窗体实现的槽函数中展示鼠标移动时,物理坐标(视图坐标)、场景坐标、图形项的坐标
自定义扩展GraphicsView组件
主界面设计
View组件提升为TGraphicsView
定义矩形区域,设置为场景
//1. 创建一个区域 从 -200,-100开始,长400宽200QRectF 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 高100QGraphicsEllipseItem *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);//设置鼠标跟踪后,才能获取到mouseMoveEventui->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();
}