QGraphicsView中如果我们设置了setDragMode(QGraphicsView::ScrollHandDrag),启用拖拽功能。游标(光标)的样式默认是Qt::OpenHandCursor。如图:
我们想实现的功能是, 当光标悬浮时处于箭头状态,按下鼠标左键再显示成手形样式。如下图我们想要的效果。
我们在继承自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);
}