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

问题描述:

我想允许用户使用鼠标在图像上绘制线条, 我正在使用图形视图和鼠标事件,但我得到的位置不是正确的位置相对到图像 这里是鼠标事件函数qt在图形视图中获取鼠标相对于图像的位置

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; 
      } 
     } 
    } 
} 

这应该画一个点(我与一个像素长线替换它看起来像一个点)

现在,我得到红点远离鼠标点击如图所示 enter image description here

我怎样才能确切地在鼠标光标上?

编辑:

我做了一个自定义类图形场景相对点击得到它,我试图重写鼠标按下图像查看,但现场的尺寸与图形视图和点一样还是远鼠标点击

覆盖鼠标在我的自定义场景按下并没有太大的帮助,因为我总是得到0,0位置点击场景无论在哪里我点击

新文件代码:

报头F ILE

#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 

源文件

#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); 
} 
+1

首先,我会建议处理QGraphicsScene的'mousePressEvent'(http://doc.qt.io/qt-5/qgraphicsscene.html#mousePressEvent)...第二,我想知道为什么你在每个'mousePress'上创建一个新场景,pixmap和line-item? – Robert

+0

这是不好的做法,你是对的,我很急,所以没有注意到,我会考虑让他们一次,并删除他们在析构,谢谢你提醒我 –

+0

我也将检查链接,让我知道如果我有任何问题 –

如果要添加QGraphicsLineItem,则必须使用场景的系统坐标,因此必须使用scenePos()方法的QGraphicsSceneMouseEvent方法和方法mapFromScene()的项目功能。

为此,我们必须覆盖的方法mousePressEventmouseMoveEventQGraphicsScenemouseReleaseEvent,以上所有我在下面的类中实现它:

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); 
    } 

}; 

完整的代码是基于以下link

+0

真棒,有效,完全scenepos而不是pos是解决方案。谢谢 –

既然你是超负荷对话的鼠标事件,你有对话的坐标鼠标位置。最好使用绘图小部件事件让Qt为你做所有对话并且不过滤对话区域。

为了使其真正可重用,您可以实现QGraphicsItem Drawable子类,并在其中添加或编辑子项时处理鼠标事件。

编辑 这里是工作的例子,你qt-drawable-item-example

简述:

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; 
} 
+0

我为QGraphicsScene做了这些,我怎么编辑它来尝试QGraphicsItem呢?请参阅编辑问题 –

+0

@AmmarAtef,请检查答案的编辑。我在那里添加了回购链接。 –

+0

非常感谢 –

您收到的InitializationDialog但不是你的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); 
+0

那没有用 –

+0

什么是你的层次结构?可能你有一些滚动视图。只需在绘制图像的类内部实现鼠标事件。 –