2017-09-05 59 views
0

我想允許用戶使用鼠標在圖像上繪製線條, 我正在使用圖形視圖和鼠標事件,但我得到的位置不是正確的位置相對到圖像 這裏是鼠標事件函數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

我也將檢查鏈接,讓我知道如果我有任何問題 –

回答

2

如果要添加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是解決方案。謝謝 –

1

既然你是超負荷對話的鼠標事件,你有對話的座標鼠標位置。最好使用繪圖小部件事件讓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

非常感謝 –

1

您收到的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

什麼是你的層次結構?可能你有一些滾動視圖。只需在繪製圖像的類內部實現鼠標事件。 –