[英]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
的方法mousePressEvent
, mouseMoveEvent
和mouseReleaseEvent
,以上所有这些我都在以下类中实现了:
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);
}
};
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.