This widget is one of several components. I need the cursor to change just on the widget itself and not on the entire application so the override cursor is not an option.

So I took your suggestion and implemented a custom event (with the code below), but the event is processed before returning back to qgraphicsview and same issue happens :-(

I even added the ability to change the viewport cursor from the view context menu, and the same thing happens . . . the set cursor and the change cursor event are happening before the qv mouse move event and when it returns to the mouse event, it sets the cursor to the original "unwanted" cursor.

Qt Code:
  1. #ifndef __EVENT_H__
  2. #define __EVENT_H__
  3.  
  4. #include <QEvent>
  5. #include <QCursor>
  6.  
  7. class SetCursorEvent : public QEvent
  8. {
  9. public:
  10. SetCursorEvent( const QCursor & cursor )
  11. : QEvent( SetCursorEvent::type() ),
  12. m_cursor( cursor )
  13. {}
  14.  
  15. virtual ~SetCursorEvent()
  16. {}
  17.  
  18. static QEvent::Type type()
  19. {
  20. return EventType;
  21. }
  22.  
  23. QCursor cursor() const
  24. {
  25. return m_cursor;
  26. }
  27.  
  28. private:
  29. static QEvent::Type EventType;
  30. QCursor m_cursor;
  31. };
  32.  
  33. #endif
To copy to clipboard, switch view to plain text mode 
Qt Code:
  1. #ifndef __VIEW_H__
  2. #define __VIEW_H__
  3.  
  4. #include "event.h"
  5.  
  6. #include <QDebug>
  7. #include <QEvent>
  8. #include <QGraphicsView>
  9.  
  10. class View : public QGraphicsView
  11. {
  12. Q_OBJECT
  13.  
  14. public:
  15. View( QWidget* parent = 0 ) : QGraphicsView( parent )
  16. {
  17. setFrameStyle( QFrame::NoFrame );
  18. setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  19. setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
  20. }
  21.  
  22. protected:
  23. bool viewportEvent( QEvent * event )
  24. {
  25. if( QEvent::CursorChange == event->type() )
  26. {
  27. qDebug() << "Cursor Change:" << viewport()->cursor().shape();
  28. }
  29. else if( SetCursorEvent::type() == event->type() )
  30. {
  31. SetCursorEvent * e = static_cast<SetCursorEvent*>(event);
  32. qDebug() << "SetCursorEvent:" << e->cursor().shape();
  33. viewport()->setCursor( e->cursor() );
  34. }
  35. return QGraphicsView::viewportEvent(event);
  36. }
  37. };
  38.  
  39. #endif
To copy to clipboard, switch view to plain text mode 
Qt Code:
  1. #include "event.h"
  2. #include "window.h"
  3. #include "view.h"
  4. #include "item.h"
  5.  
  6. #include <QAction>
  7. #include <QApplication>
  8. #include <QGraphicsScene>
  9. #include <QMenu>
  10.  
  11. QEvent::Type SetCursorEvent::EventType =
  12. static_cast<QEvent::Type>(QEvent::registerEventType());
  13.  
  14. Window::Window( QWidget * p )
  15. : QMainWindow( p )
  16. {
  17. m_scene = new QGraphicsScene( 0, 0, 1000, 1000);
  18. m_scene->setBackgroundBrush(QBrush(Qt::black, Qt::SolidPattern));
  19.  
  20. m_view = new View;
  21. m_view->setScene(m_scene);
  22. m_view->fitInView( m_scene->sceneRect() );
  23. setCentralWidget(m_view);
  24.  
  25. m_view->setContextMenuPolicy( Qt::CustomContextMenu );
  26. connect( m_view,
  27. SIGNAL( customContextMenuRequested(const QPoint &) ),
  28. SLOT( viewContextMenu(const QPoint &) ) );
  29.  
  30. m_view->viewport()->setCursor( Qt::CrossCursor );
  31. }
  32.  
  33. Window::~Window()
  34. {
  35. }
  36.  
  37. void Window::viewContextMenu( const QPoint & pt )
  38. {
  39. QMenu contextMenu;
  40. QAction * act;
  41.  
  42. contextMenu.addAction( tr("Extract Item") );
  43. contextMenu.addAction( tr("Change Cursor") );
  44.  
  45. act = contextMenu.exec( m_view->viewport()->mapToGlobal(pt) );
  46. if( NULL != act )
  47. {
  48. switch( contextMenu.actions().indexOf(act) )
  49. {
  50. case 0:
  51. {
  52. Item *item = new Item;
  53. item->setRect( QRectF( 0, 0, 100, 100 ) );
  54. item->setPen( QPen(Qt::green) );
  55. item->setBrush( QBrush(Qt::red) );
  56. item->setPos( m_view->mapToScene(pt) );
  57. item->setCursor( Qt::SizeAllCursor );
  58. item->setFlag( QGraphicsItem::ItemIsMovable, true );
  59. connect( item,
  60. SIGNAL( requestContextMenu(const QPoint&,const QRectF&) ),
  61. SLOT( extractContextMenu(const QPoint&,const QRectF&) ) );
  62. m_scene->addItem(item);
  63.  
  64. m_view->setContextMenuPolicy( Qt::DefaultContextMenu );
  65. m_view->viewport()->setCursor( Qt::ForbiddenCursor );
  66. break;
  67. }
  68. case 1:
  69. {
  70. Qt::CursorShape shape;
  71. if( m_view->viewport()->cursor().shape() == Qt::OpenHandCursor )
  72. {
  73. shape = Qt::CrossCursor;
  74. }
  75. else
  76. {
  77. shape = Qt::OpenHandCursor;
  78. }
  79. SetCursorEvent * e = new SetCursorEvent( shape );
  80. QApplication::postEvent( m_view->viewport(), e );
  81. //m_view->viewport()->setCursor( shape );
  82. break;
  83. }
  84. }
  85. }
  86. }
  87.  
  88. void Window::extractContextMenu( const QPoint & pt, const QRectF & /*rect*/ )
  89. {
  90. QMenu contextMenu;
  91. QAction * act;
  92. Item *pGI = qobject_cast<Item*>(sender());
  93.  
  94. contextMenu.addAction( tr("Done") );
  95. contextMenu.addAction( tr("Change Cursor") );
  96.  
  97. act = contextMenu.exec( pt );
  98. if( NULL != act )
  99. {
  100. switch( contextMenu.actions().indexOf(act) )
  101. {
  102. case 0:
  103. {
  104. m_view->setContextMenuPolicy( Qt::CustomContextMenu );
  105. m_view->scene()->removeItem( pGI );
  106. delete pGI;
  107. //m_view->viewport()->setCursor( Qt::CrossCursor );
  108. SetCursorEvent * e = new SetCursorEvent( Qt::CrossCursor );
  109. QApplication::postEvent( m_view->viewport(), e );
  110. break;
  111. }
  112. case 1:
  113. {
  114. //m_view->viewport()->setCursor( Qt::WaitCursor );
  115. SetCursorEvent * e = new SetCursorEvent( Qt::WaitCursor );
  116. QApplication::postEvent( m_view->viewport(), e );
  117. break;
  118. }
  119. }
  120. }
  121. }
To copy to clipboard, switch view to plain text mode