【Qt系列】实时显示鼠标位于QGraphicsView或QGraphicsScene坐标点

演示效果

在这里插入图片描述
坐标点的显示在右下角。

前言

在Graphics View框架结构主要包含三个类:场景类(QGraphicsScene)、视图类(QGraphicsView)和图元类(QGraphicsItem),统称为“三要素”。这三要素都有自己的坐标系,各个坐标系之间可以相互转换。这次博客主要实现的就是展现鼠标在其中两个坐标系的坐标点。

场景坐标

场景坐标是所有图元的基础坐标系统。场景坐标系统描述了顶层图元的位置,并且构成从视图传播到场景的所有场景事件的基础。每个图元在场景上都有场景坐标和边界矩形。场景坐标的原点在场景中心,坐标原点是X轴正方向向右,Y轴正方向向下。
在这里插入图片描述

视图坐标

视图坐标是窗口部件的坐标,视图坐标的单位是像素,QGraphicsView的左上角是(0,0)。所有鼠标事件、拖拽事件最开始都使用视图坐标,为了和图元交互,需要转换坐标为场景坐标。
在这里插入图片描述

代码讲解

class AgvView : public QGraphicsView
{
public:
    AgvView();

    QLabel *scenePointDispaly = new QLabel;

protected:
    void mouseMoveEvent(QMouseEvent *event);    //鼠标移动事件

private:
    QPointF scenePoint;
};

首先我们要新建一个类,这个新的类是基于QGraphicsView类的,继承了它的功能。然后我们要重新编写mouseMoveEvent函数,即鼠标移动函数,这是个虚函数,我们可以重新定义它的功能。

这个mouseMoveEvent函数是继承自QWidget类的虚函数,凡是继承自QWidget类的子类都可以重新实现该函数,去接收在控件上的鼠标移动事件。基本上大多数控件都是继承自QWidget类的。

//鼠标移动事件
void AgvView::mouseMoveEvent(QMouseEvent *event)
{
    //QGraphicsView坐标
    QPoint viewPoint = event->pos();

    //QGraphicsScene坐标
    scenePoint = mapToScene(viewPoint);
    setMouseTracking(true);
    scenePointDispaly->setText("("+QString::number(scenePoint.x())+","+QString::number(scenePoint.y())+")");
 
}

实现代码也很简单,event事件有个pos函数,返回此时鼠标所在的位置,返回数据类型是QPoint。因为该鼠标事件位于View事件,所以pos函数返回的也是相对于View坐标系的坐标点。如果是需要显示View坐标坐标点,那这个用这个参数就可以了。

也可以通过mapToScene函数,将View坐标点映射到Scene坐标系,得到Scene坐标点。最后将对应坐标点的x和y展示在QLabel标签上。

QLabel标签是类声明的public属性的控件,以便可以添加到布局里面显示。当然也有其他方法显示,反正数据scenePoint就在那。

setMouseTracking函数主要是设置是否开启鼠标跟踪。如果鼠标跟踪失能(默认情况),只有鼠标其中一个按键按下且移动的时候,控件才会进入鼠标事件。如果鼠标跟踪使能,即使没有按下鼠标,只要移动了,就会进入鼠标事件。

我想要实现的功能是鼠标滑过或者停留在上面,就能显示坐标点,所以选择了使能true。感觉拖拽很不方便。

    QLabel *label1 = new QLabel;
    label1->setText("Scene坐标点:");
    tab3LayoutR->addWidget(label1);      //添加两个文本控件
    tab3LayoutR->addWidget(view->scenePointDispaly);

将这个标签QLabel添加到主界面其中一个布局就可以了。

  • 4
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 在Qt中使用鼠标QGraphicsView上画直线,可以按照以下步骤进行操作: 首先,在QGraphicsView的构造函数中设置鼠标追踪,以便能够捕捉鼠标事件: ``` QGraphicsView::QGraphicsView(QWidget *parent) : QGraphicsView(parent) { setMouseTracking(true); //... } ``` 然后,重写QGraphicsView的mousePressEvent、mouseMoveEvent和mouseReleaseEvent函数,以便在鼠标按下、拖动和释放时进行相应的操作: ``` void QGraphicsView::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { startPoint = event->pos(); } } void QGraphicsView::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { endPoint = event->pos(); // 绘制直线 QGraphicsLineItem *line = new QGraphicsLineItem(QLineF(startPoint, endPoint)); scene()->addItem(line); } } void QGraphicsView::mouseReleaseEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { endPoint = event->pos(); // 绘制直线 QGraphicsLineItem *line = new QGraphicsLineItem(QLineF(startPoint, endPoint)); scene()->addItem(line); } } ``` 在鼠标按下和拖动过程中,计算起和终位置,并通过QGraphicsLineItem将直线添加到场景中,从而实现直线的绘制。 需要注意的是,上述代码只是一个简单的示例,没有包含完整的界面和场景创建过程。在实际应用中,需要创建一个自定义的QGraphicsView,并在其中创建一个QGraphicsScene来进行操作。 通过上述步骤,我们就可以使用鼠标QGraphicsView上画直线了。 ### 回答2: 在使用Qt中的QGraphicsView绘制直线,可以按照以下步骤进行操作: 1. 创建一个继承自QGraphicsView的自定义视图类,例如MyGraphicsView,并在构造函数中进行初始化设置,如设置背景、启用鼠标追踪等。 2. 重写MyGraphicsView中的mousePressEvent和mouseReleaseEvent函数,以响应鼠标按下和释放事件。在mousePressEvent中记录起始坐标,并在mouseReleaseEvent中记录结束坐标。 3. 在MyGraphicsView类中添加一个成员变量QGraphicsLineItem *lineItem,用于存储并显示绘制的直线。 4. 在mousePressEvent中创建一个QPen,设置直线的颜色、宽度等属性。然后,通过scene()函数获取视图的场景对象,使用scene()->addLine函数创建一个QGraphicsLineItem对象,并且将其赋值给lineItem成员变量。 5. 在mouseReleaseEvent中获取结束坐标,并根据起始和结束坐标在scene()中移除之前创建的直线对象。然后,使用scene()->addLine函数创建新的直线对象,并将其赋值给lineItem成员变量。这样可以实现直线随着鼠标移动而动态绘制的效果。 6. 最后,更新视图来显示添加的直线。可以使用视图的invalidateSceneRect函数来刷新视图。 综上所述,通过重写鼠标事件函数,在鼠标按下和释放事件中获取坐标并绘制直线,可以实现用鼠标QGraphicsView中画直线的效果。 ### 回答3: 在Qt中,要使用鼠标QGraphicsView上画直线,可以通过以下步骤实现: 首先,创建一个继承自QGraphicsView的自定义视图类,并重写其中的鼠标事件函数: ```cpp class MyGraphicsView : public QGraphicsView { Q_OBJECT public: MyGraphicsView(QWidget *parent = nullptr) : QGraphicsView(parent) {} protected: void mousePressEvent(QMouseEvent *event) override { if(event->button() == Qt::LeftButton) // 按下鼠标左键 { startPoint = event->pos(); // 记录起始 } } void mouseReleaseEvent(QMouseEvent *event) override { if(event->button() == Qt::LeftButton) // 松开鼠标左键 { endPoint = event->pos(); // 记录结束 QGraphicsScene *scene = this->scene(); // 获取当前场景 scene->addLine(QLineF(startPoint, endPoint)); // 在场景上添加直线 update(); // 更新视图 } } private: QPointF startPoint; // 直线起始 QPointF endPoint; // 直线结束 }; ``` 然后,在主窗口中创建一个QGraphicsView对象,并将其设置为自定义视图类: ```cpp QGraphicsView *view = new MyGraphicsView(this); ``` 最后,将视图对象添加到布局中,并显示主窗口: ```cpp QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(view); QWidget *widget = new QWidget; widget->setLayout(layout); setCentralWidget(widget); show(); ``` 以上代码实现了在QGraphicsView中通过鼠标画直线的功能。当鼠标按下时记录起始,当鼠标松开时记录结束,并在场景中添加直线。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值