同时将MouseMoveEvent用于QGraphicsScene和HoverEnterEvent用于QGraphicsItem

问题描述 投票:1回答:1

我正在尝试创建一个程序,您可以在其中将点和线连接在一起。我将QGraphicsEllipseItem实例化为QGraphicsScene,并使用HoverEnterEvent和HoverLeaveEvent来改变鼠标悬停时椭圆的颜色和大小。要在单击的点和鼠标光标之间绘制一条临时线,我必须使用MouseMoveEvent进入场景。但是,当我这样做时,项的HoverEvents不再起作用!如何同时使用场景的MouseMoveEvent和项目的HoverEvents?

enter image description here

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    for (int i = 0; i < pointList.size(); ++i) {
        if (pointList[i]->over == 1){
            pointList[i]->press();
            lineActivated=true;
            tempLine.setLine(pointList[i]->x(),pointList[i]->y(),pointList[i]->x(),pointList[i]->y());
        }
    }
}

void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{

    if(lineActivated){
        const QPointF pos = event->scenePos();
        tempLine.setP2(pos);
    }
}


void Point::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    pen.setColor(Qt::green);
    pen.setWidth(2);
    this->setPen(pen);
    over=true;
    qDebug("enter");
    update();
}

void Point::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    if(isClicked==false){
        pen.setColor(Qt::lightGray);
        pen.setWidth(1);
        over=false;
        this->setPen(pen);
        qDebug("leave");
        update();
    }
}

qt mouseevent qgraphicsscene qgraphicsitem mousehover
1个回答
1
投票

默认情况下,QGraphicsScene::mouseMoveEvent发送必要的信息来处理项目的悬停事件,但会覆盖该方法,从而消除了该行为。解决方法是调用父方法。

#include <QtWidgets>

class GraphicsScene: public QGraphicsScene{
public:
    using QGraphicsScene::QGraphicsScene;
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event){
        if(!m_lineitem){
            m_lineitem = new QGraphicsLineItem;
            addItem(m_lineitem);
        }
        QLineF l(event->scenePos(), event->scenePos());
        m_lineitem->setLine(l);
        QGraphicsScene::mousePressEvent(event);
    }
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event){
        if(m_lineitem){
            QLineF l(m_lineitem->line().p1(), event->scenePos());
            m_lineitem->setLine(l);
        }
        QGraphicsScene::mouseMoveEvent(event);
    }
private:
    QGraphicsLineItem *m_lineitem = nullptr;
};

class Point: public QGraphicsEllipseItem{
public:
    Point(QGraphicsItem *parent=nullptr): QGraphicsEllipseItem(parent){
        setRect(QRectF(-5, -5, 10, 10));
        QPen pen;
        pen.setColor(Qt::lightGray);
        pen.setWidth(1);
        setPen(pen);
        setAcceptHoverEvents(true);
    }
protected:
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event){
        QPen pen;
        pen.setColor(Qt::green);
        pen.setWidth(2);
        setPen(pen);
        QGraphicsEllipseItem::hoverEnterEvent(event);
    }
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *event){
        QPen pen;
        pen.setColor(Qt::lightGray);
        pen.setWidth(1);
        setPen(pen);
        QGraphicsEllipseItem::hoverLeaveEvent(event);
    }
};

int main(int argc, char *argv[]){
    QApplication a(argc, argv);
    GraphicsScene *scene = new GraphicsScene;
    QGraphicsView w(scene);
    w.setRenderHint(QPainter::Antialiasing, true);
    w.fitInView(QRectF(0, 0, 100, 100), Qt::KeepAspectRatio);
    for(const QPointF & p: {QPointF(10.0, 10.0), QPointF(90.0, 20.0), QPointF(30.0, 40.0)}){
        Point *it = new Point();
        scene->addItem(it);
        it->setPos(p);
    }
    w.resize(640, 480);
    w.show();
    return a.exec();
}
© www.soinside.com 2019 - 2024. All rights reserved.