1

我正在开发一个使用 Qt 4.8 作为 GUI 框架的 C++ 应用程序:一个子类 QGraphicsView 呈现一个子类 QGraphicsScene,其中包含一个或多个子类 QGraphicsPixMapItem(s),我需要知道鼠标光标的相对像素位置。

按照如何从 QGraphicsPixmapItem 显示像素位置和颜色,我将 QGraphicsPixmapItem 子类

class MyGraphicsPixmapItem : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT
public:
    explicit MyGraphicsPixmapItem(QGraphicsItem *parent = 0);
signals:
public slots:
    void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
};

并实现构造函数和处理程序:

MyGraphicsPixmapItem::MyGraphicsPixmapItem(QGraphicsItem *parent) : QGraphicsPixmapItem(parent)
{
    qDebug() << "constructor mygraphicspixmapitem";
    setCacheMode(NoCache);
    setAcceptHoverEvents(true);
    setFlag(QGraphicsItem::ItemIsSelectable,true);
}

void MyGraphicsPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
    QPointF mousePosition = event->pos(); 
    qDebug() << "mouseMoveEvent";
    qDebug() << mousePosition;
    QGraphicsPixmapItem::mouseMoveEvent(event);
}

我还使用各自的 mouseMoveEvent 处理程序将 QGraphicsView 和 QGraphicsScene 子类化,这些处理程序可以成功地进一步向下传递事件:

void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << "QGraphicsScene: mouseMoveEvent";
    QGraphicsScene::mouseMoveEvent(event);
}

然而,虽然 MyGraphicsView 配置了...

setMouseTracking(true);
setInteractive(true);

... MyGraphicsPixmapItem 仅在单击或将其设置为抓取器后执行 mouseMoveEvent 处理程序:

void MyGraphicsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    qDebug() << QString("item clicked at: %1, %2").arg( event->pos().x()).arg( event->pos().y()  );
    event->accept();
    grabMouse();
}

我想知道我是否犯了错误,或者上述答案中给出的解决方案有缺陷或不完整。此外,我想知道是否可以在没有将 QGraphicsPixmapItem 配置为“grabber”的情况下触发 mouseMoveEvent 处理程序。如果在鼠标第一次移动到项目上时自动发生作为抓取器的配置也是可以接受的。

这是一个线程,其中一个非常相似的问题似乎与项目的引用有关,但由于我将项目添加到场景中,如下所示:

thepixMapItem = new MyGraphicsPixmapItem();
scene->addItem(thepixMapItem);

我想这没有关系。

4

1 回答 1

1

解决方案是重新实现或过滤项目的hoverMoveEvent,因为mouseMoveEvent仅在收到鼠标按下时触发:

如果你确实收到了这个事件,你可以确定这个项目也收到了一个鼠标按下事件,并且这个项目是当前的鼠标抓取器。

于 2013-07-16T13:45:51.343 回答