Results 1 to 9 of 9

Thread: qgraphicsview cursor setting logic

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Nov 2009
    Location
    San Antonio, TX
    Posts
    69
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt Jambi
    Platforms
    Unix/X11 Windows

    Default Re: qgraphicsview cursor setting logic

    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 

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: qgraphicsview cursor setting logic

    In that case use a singleshot timer or QMetaObject::invokeMethod() to call the cursor change functionality with a small delay (e.g. 20ms). The delay will not be noticable to the user.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Nov 2009
    Location
    San Antonio, TX
    Posts
    69
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt Jambi
    Platforms
    Unix/X11 Windows

    Default Re: qgraphicsview cursor setting logic

    With singleShot timer, I can get the delay but the single/slot does not allow any arguments, eg new cursorMask . . . but I can probably work around that.
    With invokeMethod, I can call the needed method with the proper argument, but I do not see a way to specify a delay? Am I missing something? Or are you saying to just use a 20 ms sleep?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: qgraphicsview cursor setting logic

    Quote Originally Posted by mcarter View Post
    With singleShot timer, I can get the delay but the single/slot does not allow any arguments, eg new cursorMask . . . but I can probably work around that.
    With invokeMethod, I can call the needed method with the proper argument, but I do not see a way to specify a delay? Am I missing something? Or are you saying to just use a 20 ms sleep?
    No, no sleep(). You can store the "argument" in some member variable and then fetch it from there when the timer fires.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Nov 2009
    Location
    San Antonio, TX
    Posts
    69
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt Jambi
    Platforms
    Unix/X11 Windows

    Default Re: qgraphicsview cursor setting logic

    Right, no sleep . . . was just thinking how to use the invokeMethod.

    I implemented the singleShot timer, and while it works with my linux laptop, it does not seem to work on my windows test machine. The cursor changes, but once I move the mouse it reverts to the previous cursor again.

    I did find QTBUG-3732 and QTBUG-4190 in the Qt bug reports, which both seem exactly related to what I am seeing. However, they are both closed (2009/2010). What is the best procedure to re-open these bugs, because it looks like an obvious logic problem with the cursor and graphicsview. My suggestion would be to get rid of the internal originalCursor and use the cursor of the GraphicsView, since that it not really used anywhere, for the cursor of the viewport. I guess in the meantime I need to abort what I am trying to accomplish or try to "fix" graphicsview with my oen code.

    Also, when I was working in windows, I noticed that the cursors are really unusable with a view that is mostly black (especially CrossCursor) . . . the cursor just "disappears". Do I need to use a custom cursor to get the same feel as with linux and X11?

Similar Threads

  1. Replies: 3
    Last Post: 3rd September 2012, 07:32
  2. Setting manually cursor position on multi screen systems
    By irreriwan in forum Qt Programming
    Replies: 0
    Last Post: 4th March 2008, 09:47
  3. Setting a cursor on QTextEdit
    By Erlendhg in forum Qt Programming
    Replies: 6
    Last Post: 20th March 2007, 17:53
  4. setting Cursor for one operation
    By keshab in forum Newbie
    Replies: 1
    Last Post: 22nd December 2006, 08:09
  5. setting cursor problem in QTextEdit
    By jyoti kumar in forum Qt Programming
    Replies: 3
    Last Post: 19th May 2006, 08:17

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.