• 13172阅读
  • 10回复

graphics view框架中item的鼠标坐标? [复制链接]

上一主题 下一主题
离线luosw27
 
只看楼主 倒序阅读 楼主  发表于: 2011-03-28
在graphics item的mouseMoveEvent(QGraphicsSceneMouseEvent*event)中,如何得到当前鼠标的坐标点?我需要对坐标点判断是否移出item的范围。
对于event的获取坐标点的函数,比如 QPointF pos()const; QPointF lastPos()const; 这两个都获取到y值很大,
QPointscreenPos()const;

QPointlastScreenPos()const
这两个则是屏幕的坐标。
莫非只能拿屏幕坐标转换成view坐标,再转换成scene坐标,然后才能判断当前鼠标还在不在item上?
一定是有其他更好的办法的,大侠们给点宝贵意见,谢谢!!

[ 此帖被luosw27在2011-03-28 19:09重新编辑 ]
离线luosw27
只看该作者 1楼 发表于: 2011-03-28
实在是给那些转换函数搞晕了。哪位大虾举例解说下各个转换函数

坐标映射
经常,处理场景中item时,在场景与item之间,item与item之间,视图与场景之间进行坐标映射,形状映射是非常有用的。举例来讲,当你在QGraphicsView的视口中点击鼠标时,你应该通过调用QGraphicsView::mapToScence()与QGraphicsScene::itemAt()来获知光标下是场景中的哪个item。假如你想获知一个item位于视口中的什么位置,你应该先在item上调用QGraphicsItem::mapToScene(),然后调用QGraphicsView::mapFromScene()。最后,假如你想在一个视图椭圆中有哪些items,你应该把QPainterPath传递到mapToScene(),然后再把映射后的路径传递到QGraphicsScene::items()。
你可以调用QGraphicsItem::mapToScene()与QGraphicsItem::mapFromScene()在item与场景之间进行坐标与形状的映射。也可以在item与其父item之间通过QGraphicsItem::mapToParent()与QGraphicsItem::mapFromItem()进行映射。所有映射函数可以包括点,矩形,多边形,路径。视图与场景之间的映射也与此类似。对于从视图与item之间的映射,你应该首先映射到场景,然后再从场景向item进行映射。


离线luosw27
只看该作者 2楼 发表于: 2011-03-28
我需要从qgraphicsitem派生出具有按钮行为的控件,能独立调用,不要跟view和scene绑在一起。
离线sbtree
只看该作者 3楼 发表于: 2011-03-28
纠正一点:item之间也可以通过mapFromItem和mapToItem在同一个scene中直接转换
windows 7 + VC++2008 + Qt4.5.2
离线sbtree
只看该作者 4楼 发表于: 2011-03-28
另外,item还有三个虚拟函数你可以考虑重写,可以直接在鼠标移入,移动和移出shape的时候相应
virtual void    hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
virtual void    hoverMoveEvent ( QGraphicsSceneHoverEvent * event )
virtual void    hoverEnterEvent ( QGraphicsSceneHoverEvent * event )

注:在这三个函数起作用之前,需要调用item的setAcceptHoverEvents (true )
[ 此帖被sbtree在2011-03-28 22:57重新编辑 ]
windows 7 + VC++2008 + Qt4.5.2
离线luosw27
只看该作者 5楼 发表于: 2011-03-29
谢谢sbtree!
我还是不明白,为什么我在mouseMoveEvent(QGraphicsSceneMouseEvent *event)中获取event的pos值很奇怪,为(0,1080074240),这是在item坐标系下的值,但我的ITEM大小才170*170,。
我检查了下创建scene和item的代码,都有进行位置设置。
view类:setGeometry(0,0,800,480);
scene类: setSceneRect(0,0,800,480);
addItem(pBtn);
pBtn->setPos(100, 100);
显示出来的效果是正确的,就是获取的坐标不对。
封装slider等控件的话,我需要鼠标移动的坐标值。
离线luosw27
只看该作者 6楼 发表于: 2011-03-29

virtual void    hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )

重新编译后,可以获取到鼠标离开item范围的消息,但我需要知道按下左键并移动的范围,鼠标的坐标点对我来说很重要。
简化代码后,就只剩下下面一点点了,高手看看哪里的问题,谢谢!
代码如下:
view类
MyGraphView::MyGraphView(QWidget *parent): QGraphicsView(parent)
{
  QGraphicsScene *scene = new QGraphicsScene(this);
  scene->setItemIndexMethod(QGraphicsScene::NoIndex);
  scene->setSceneRect(0, 0, 800, 480);
  setScene(scene);
  setCacheMode(CacheBackground);
  setViewportUpdateMode(BoundingRectViewportUpdate);
  setRenderHint(QPainter::Antialiasing);
  setTransformationAnchor(AnchorUnderMouse);

  setFixedSize(800, 480);
  setFrameShape(QFrame::NoFrame);
  setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

  setMouseTracking(true);
  centerNode = new MyItem(this);
  scene->addItem(centerNode);
  centerNode->setPos(100, 100);
}

item类
MyItem::MyItem(MyGraphView *graphWidget)
  : graph(graphWidget)
{
  setFlag(ItemIsSelectable);
  setFlag(ItemSendsGeometryChanges);
  setCacheMode(DeviceCoordinateCache);
  m_enStatus = enNormal;
}

void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
  painter->drawEllipse(0, 0, 170, 180);
}
QRectF MyItem::boundingRect() const
{
  return QRectF(0 , 0 , 170 , 180);
}
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
  qDebug("MyItem::mousePressEvent: %d-%d\n", event->pos().x(), event->pos().y());
  m_enStatus = enNormal;
  update();
  QGraphicsItem::mousePressEvent(event);
}

void MyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
  qDebug("MyItem::mouseReleaseEvent: %d-%d\n", event->pos().x(), event->pos().y());
  m_enStatus = enNormal;
  update();
  QGraphicsItem::mouseReleaseEvent(event);
}

没几行代码,原想myItem模拟按钮。简化后就是以上代码,我测试发现同样获取坐标不对。

[ 此帖被luosw27在2011-03-30 09:31重新编辑 ]
离线luosw27
只看该作者 7楼 发表于: 2011-04-01
qDebug("MyItem::mousePressEvent: %d-%d\n", event->pos().x(), event->pos().y());
改为
qDebug("MyItem::mousePressEvent: %d-%d\n", (int)event->pos().x(), (int)event->pos().y());

出来的结果就正确了,太诡异了吧!
qreal int两种数据类型相差那么远吗?
离线owenvslili
只看该作者 8楼 发表于: 2011-05-16
你可以用 event->scenePos()来获取图元在scene中坐标
离线medky

只看该作者 9楼 发表于: 2013-01-31
qreal int两种数据在内存布局上面确实是差很远的。
离线qxwq123t

只看该作者 10楼 发表于: 2013-02-11
了解,谢谢提供。
快速回复
限100 字节
 
上一个 下一个