图形/视图结构的三个坐标系分别为视图结构系=物理结构系,场景坐标系,图形项坐标系。
本文记录实践三个坐标系及视图与场景坐标转换,通过事件槽来显示出来的过程。
- 自定义1个View视图组件,其中扩展了鼠标点击、鼠标移动的事件,在这两个事件中分别发送/广播了信号 鼠标按下左键、鼠标移动的信号
- 在主窗体中,使用该自定义的视图组件,
- 定义1个矩形框,然后将矩形框设置为场景
- 在该场景中添加1个蓝色椭圆图形项,1个红色圆的图形项
- 通过槽函数展示
在主窗体中,接收自定义组件发出的鼠标移动、鼠标点击左键的信号,在主窗体实现的槽函数中展示鼠标移动时,物理坐标(视图坐标)、场景坐标、图形项的坐标
自定义扩展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();
}