往期回顾
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里基本图元绘制的简单介绍。
都看到这里了,点个赞再走呗朋友~
加油吧,预祝大家变得更强!