简体   繁体   English

qt在图形视图中获得鼠标单击相对于图像的位置

[英]qt get mouse clicked position relative to image in a graphics view

I want to allow user to draw lines on image using the mouse, I'm using graphics view and mouse event but the position I get is not the right position relative to the image here is the mouse event function 我想允许用户使用鼠标在图像上画线,我正在使用图形视图和鼠标事件,但是我得到的位置相对于图像而言不是正确的位置,这里是鼠标事件功能

void InitializationDialog::mousePressEvent(QMouseEvent *event) {
    if(drawing) {
        points.append(event->pos());
        if(!points.isEmpty()) {
            if(points.size()==1) {
                QString fileName = list.at(choosed);
                QImage image(fileName);
                QGraphicsScene* scene = new QGraphicsScene();
                QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
                scene->addItem(item);
                QColor color(255,0,0);
                QBrush brush(color);
                QPen pen(brush, 4);
                QGraphicsLineItem* line = new QGraphicsLineItem(points.at(0).x(),points.at(0).y(),points.at(0).x()+1,points.at(0).y()+1);
                line->setPen(pen);
                scene->addItem(line);

                ui->graphicsView->setScene(scene);
                return;
            }
        }
    }
}

That should draw a point (I'm replacing it with one-pixel long line to look like a point) 那应该画一个点(我将其替换为一个像素的长线以看起来像一个点)

Now I get the red point far away the mouse click like shown in that image 现在,我将红点移到远离鼠标单击的位置,如该图像所示 在此处输入图片说明

How can I make it exactly on the mouse cursor? 我如何才能准确地将其放在鼠标光标上?

Edit: 编辑:

I made a custom class for graphics scene to get the click relative to it, I tried overriding mouse pressed for graphics view but the scene is not the same size as graphics view and the point still away the mouse click 我为图形场景创建了一个自定义类以获取相对于其的单击,我尝试覆盖鼠标以单击图形视图,但是该场景与图形视图的大小不同,并且该点仍然远离鼠标单击

overriding mouse pressed in my custom scene didn't help much because I always get 0,0 position for clicking the scene no matter where I click 在自定义场景中按下覆盖鼠标没有太大帮助,因为无论单击何处,我总是获得0,0的位置来单击场景

new files code: 新文件代码:

header file 头文件

#ifndef INITGRAPH_H
#define INITGRAPH_H
#include <QtGui>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPoint>
#include <QGraphicsSceneMouseEvent>
class InitGraph : public QGraphicsView {
    Q_OBJECT
public:
    InitGraph(QWidget *parent = 0);
    virtual ~InitGraph() {};
};

class CustomScene : public QGraphicsScene {
    Q_OBJECT
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
signals:
    void pressed(QPoint p);
};
#endif // INITGRAPH_H

the source file 源文件

#include "initgraph.h"
InitGraph::InitGraph(QWidget *parent):QGraphicsView(parent)
{
}
void CustomScene::mousePressEvent(QGraphicsSceneMouseEvent *event){
    qDebug(QString::number(event->pos().rx()).toLatin1());
    QPoint p = event->pos().toPoint();
    emit pressed(p);
}

If you want to add a QGraphicsLineItem you must use the system coordinates of the scene for this you must use the function the scenePos() method of QGraphicsSceneMouseEvent and the method mapFromScene() of the items. 如果你想添加一个QGraphicsLineItem的场景,你必须使用系统协调为此,你必须使用功能scenePos()的方法QGraphicsSceneMouseEvent和方法mapFromScene()的项目。

for this we must override the methods mousePressEvent , mouseMoveEvent and mouseReleaseEvent of QGraphicsScene , all of the above I implemented it in the following class: 为此,我们必须重写QGraphicsScene的方法mousePressEventmouseMoveEventmouseReleaseEvent ,以上所有这些我都在以下类中实现了:

class CustomScene : public QGraphicsScene
{
    Q_OBJECT
    QGraphicsLineItem *item;
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event){

        item = new QGraphicsLineItem;
        addItem(item);
        const QPointF p = event->scenePos();

        item->setPos(p);
    }

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event){
        const QPointF p  =item->mapFromScene(event->scenePos());
        QLineF l = item->line();
        l.setP2(p);
        item->setLine(l);
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
        const QPointF p  =item->mapFromScene(event->scenePos());
        QLineF l = item->line();
        l.setP2(p);
        item->setLine(l);
    }

};

The complete code is on the following link . 完整的代码在以下链接上

Since you are overloading mouse events of dialog you have the mouse position in dialog coordinates. 由于您正在重载对话框的鼠标事件,因此鼠标位置位于对话框坐标中。 It's better to use drawing widget events to let Qt make all the conversation for you and didn't filter dialog areas. 最好使用绘图小部件事件让Qt为您进行所有对话,而不过滤对话框区域。

To make it really reusable you can implement the QGraphicsItem Drawable subclass and process mouse events there adding or editing children. 要使其真正可重用,您可以实现QGraphicsItem Drawable子类并在那里处理鼠标事件,以添加或编辑子级。

EDIT here is a working example for you qt-drawable-item-example 在这里编辑是一个适合您的工作示例qt-drawable-item-example

Briefly: 简述:

void DrawableItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
    m_activePath = new QGraphicsPathItem(this);
    m_activePath->setPen(QPen(Qt::GlobalColor(rand()%17+2), 2.0));
    m_activePath->setPath(QPainterPath(event->pos()));
}

void DrawableItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
    if(!m_activePath) {
        QGraphicsItem::mouseMoveEvent(event);
        return;
    }

    auto path = m_activePath->path();
    path.lineTo(event->pos());
    m_activePath->setPath(path);
}

void DrawableItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
    if(!m_activePath) {
        QGraphicsItem::mouseReleaseEvent(event);
        return;
    }
    m_activePath = nullptr;
}

You are receiving position of click on InitializationDialog but not on your graphicsView, so you need to convert this position by minusing x and y of your graphicsView 您收到的是InitializationDialog上的单击位置,而不是您的graphicsView上的单击位置,因此您需要通过减去graphicsView的x和y来转换此位置

QGraphicsLineItem* line = new QGraphicsLineItem(
                          points.at(0).x()-graphicsView->rect().x(), 
                          points.at(0).y()-graphicsView->rect().y(), 
                          points.at(0).x()+1, points.at(0).y()+1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM