QGraphicsView自定义游标【解决修改光标样式不起作用】

        QGraphicsView中如果我们设置了setDragMode(QGraphicsView::ScrollHandDrag),启用拖拽功能。游标(光标)的样式默认是Qt::OpenHandCursor。如图:

QGraphicsView自定义游标【解决修改光标样式不起作用】_第1张图片

        我们想实现的功能是, 当光标悬浮时处于箭头状态,按下鼠标左键再显示成手形样式。如下图我们想要的效果。

QGraphicsView自定义游标【解决修改光标样式不起作用】_第2张图片

         我们在继承自QGraphicsView类的子类中使用this->setCursor(Qt::ArrowCursor)是不起作用的。原因是QGraphicsView继承自QAbstractScrollArea类,只能通过viewport()获取view Widget。所以在QGraphicsView子类中使用viewport()->setCursor()而不是直接setCursor(),这样才能真正改变视觉上的鼠标形状。viewport()函数定义在QAbstractScrollArea类中,对于更新视图内容应该用viewport()->update(),而不是直接用update()setDragMode(QGraphicsView::ScrollHandDrag)在默认实现中设置了鼠标样式,并且每次事件都会覆盖我们设置的样式。

实现代码如下:

GraphicsViewDrag::GraphicsViewDrag(QWidget* parent)
    : QGraphicsView(parent)
{
    setStyleSheet("padding: 0px; border: 0px;");
    setMouseTracking(true);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setResizeAnchor(QGraphicsView::AnchorUnderMouse);
    setDragMode(QGraphicsView::ScrollHandDrag);//设置这里可以拖动

    //此处设置的效果只能在没有鼠标按下之前生效
    //一旦我们触发了鼠标事件,setDragMode(QGraphicsView::ScrollHandDrag)会覆盖我们的设置
    viewport()->setCursor(Qt::ArrowCursor);
}

        为了解决setDragMode(QGraphicsView::ScrollHandDrag)覆盖我们的设置,我们必须重新实现mouseReleaseEvent(QMouseEvent *event)方法,在方法内先传递Release事件,让默认先覆盖,而后我们再设置样式,覆盖默认设置。代码如下:

void GraphicsViewDrag::mouseReleaseEvent(QMouseEvent *event)
{
    //这两句必须按这种顺序。如果先设置鼠标样式,再传递event,默认实现会覆盖我们的设置
    QGraphicsView::mouseReleaseEvent(event);
    viewport()->setCursor(Qt::ArrowCursor);
}

你可能感兴趣的:(Qt及C++应用,qt,QGraphicsView,指针样式,setCursor)