Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QGraphicsView and custom Cursors

Tags:

c++

qt

qt4

I am trying to make use of a mix of custom cursors and preset cursors for my QGraphicsView. In my implementation we have created a notion of "modes" for the view. Meaning that depending on what "mode" the user is in, different things will happen on the left-click, or left-click drag. Anyway, none of that is the problem, just the context.

The problem arises when I try to change the cursor for each mode. For instance, for mode 1 we want to show the regular Arrow cursor, but for mode 2, we want to use a custom pixmap. Seemingly simple we call graphicsview->viewport()->setCursor(Qt::QArrowCursor)  when we are switching to mode 1, and graphicsview->viewport()->setCursor(our custom cursor) for mode 2. Except it doesn't work at all.

Firstly, the cursor does not change to the custom cursor. That is the first problem. However, if through another operation the drag mode of the graphics view gets set to ScrollHandDrag, the cursor will switch to the custom cursor once the drag operation is complete. Weird. But the plot thickens... Once we switch to the custom cursor, it can never be changed back to the ArrorCursor no matter how many times we call setCursor(Qt::QArrowCursor). it also doesn't seem to matter whether I call setCursor on the viewport or the graphics view itself.

So, just for fun, I added a call to graphicsview->unsetCursor() just before we want to change the cursor, and that at least rectifies the second problem. The cursor changes just fine so long as we do a little HandDragging in between. Better, but certainly not optimal. However it should be noted, that doing the unsetCursor on the viewport doesn't work. it must absolutely be done on the graphicsview - regardless of the fact that we are setting the cursor on the viewport.

To completely patch over the problem I have added these two lines after I set the cursor:

graphicsview->setDragMode(QGraphicsView::ScrollHandDrag);
graphicsview->setDragMode(QGraphicsView::NoDrag);

Which works, but ye gads!! So something magical is happening inside these two methods that fixes the problem, but glancing at the code I don't see what. Something to do with the fact that the drag mode is changing the cursor I imagine.

Just for completeness, I should also mention that the thing that triggers the mode change, is a QPushButton that has been added to the scene using QGraphicsScene->addWidget(). I don't know if that has anything to do with it, but you never know.

I am hoping that either someone could clarify why I need to make these seemingly random calls. I don't think I am doing anything wrong anywhere. Thanks in advance for any help.

EDIT: Here is an actual code example with the cursor patches as described above. You can look at and/or download them from the link below. It was a little long to paste here. I included the framework around which the cursors are changed, because I have a funny feeling that that is important somehow.

https://gist.github.com/712654

The code where the problem lies is in MyGraphicsView.cpp starting at line 104. This is where the cursor is set in the graphics view. It is exactly as described above.

Keep in mind, with the very ugly patches in place the cursors do work - more or less. Without those lines you will see very clearly the problems listed in the post above.

Also included in the link, is all the code for a mainWindow that uses the view, etc... the only thing missing are the images I am using. But the images themselves don't matter, any 16x16 pngs will do.

like image 316
Etienne de Martel Avatar asked Nov 23 '10 15:11

Etienne de Martel


Video Answer


2 Answers

I added a museReleaseEvent to solve a similar problem...

void mouseReleaseEvent(QMouseEvent *event) {
     QGraphicsView::mouseReleaseEvent(event);
     viewport()->setCursor(Qt::CrossCursor);
}

This will reset the cursor after the drag event is complete, during the drag the hand will be visible which makes sense.

like image 84
ponchietto Avatar answered Oct 19 '22 21:10

ponchietto


My solution:

view->setDragMode( QGraphicsView::ScrollHandDrag );
QApplication::setOverrideCursor( Qt::ArrowCursor );
like image 28
Jarikus Avatar answered Oct 19 '22 19:10

Jarikus