Results 1 to 3 of 3

Thread: How to change the mouse pattern of QwtPlotPicker?

  1. #1
    Join Date
    Dec 2010
    Posts
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default How to change the mouse pattern of QwtPlotPicker?

    I found if I newed a QwtPlotPicker with the selection type of QwtPicker::PolygonSelection, then I could start a pick with LeftButton, and continue the following several picks with RightButton, and end the selection with another click of LeftButton. But I want my interaction like this: start with LeftButton and continue the other picks also with LeftButton, at last end the selection by double-clicking the Left Button.
    How could I do?
    Thanks~

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,781
    Thanks
    262
    Thanked 773 Times in 763 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to change the mouse pattern of QwtPlotPicker?

    You will probably need to implement a custom QwtPickerMachine to do this, since you are asking for the same mouse event to be interpreted in two different ways depending on the state.

    You can probably use QwtPickerClickPointMachine as a base class, then override the transition() method.

    Qt Code:
    1. QwtPickerMachine::CommandList MyQwtPickerMachine::transition( const QwtEventPattern & eventPattern, const QEvent * pEvent )
    2. {
    3. QwtPickerMachine::CommandList cmdList;
    4.  
    5. switch( pEvent->type() )
    6. {
    7. case QEvent::MouseButtonPress:
    8. {
    9. if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, (const QMouseEvent *)pEvent ) )
    10. {
    11. if ( state() == 0 )
    12. {
    13. cmdList += Begin;
    14. cmdList += Append;
    15. setState(1);
    16. }
    17. else if ( state() == 1 )
    18. {
    19. cmdList += Append;
    20. }
    21. }
    22. }
    23. break;
    24.  
    25. default:
    26. cmdList = QwtPickerClickPointMachine::transition( eventPattern, pEvent );
    27. break;
    28. }
    29. return cmdList;
    30. }
    To copy to clipboard, switch view to plain text mode 

    This will handle the two interpretations of the left single-click. The state() value allows you to determine what has already happened. To handle the left double-click to end the sequence, you need another case:

    Qt Code:
    1. case QEvent::MouseButtonDblClick:
    2. {
    3. if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, (const QMouseEvent *)pEvent ) )
    4. {
    5. if ( state() == 1 )
    6. {
    7. cmdList += Append;
    8. cmdList += End;
    9. setState( 0 );
    10. }
    11. }
    12. }
    13. break;
    To copy to clipboard, switch view to plain text mode 

    Next, you need to implement a custom QwtPlotPicker class, because (at least in Qwt 5.2) there is no way to set a custom QwtPickerMachine for one of the standard QwtPicker classes.

    In this class, you need to create an instance of your customer picker machine, and reimplement the QwtPlotPicker::transition method to call your picker machine's transition() method:

    Qt Code:
    1. void MyQwtPlotPicker::transition( const QEvent * pEvent )
    2. {
    3. // "myStateMachine" is an instance of MyQwtPickerMachine
    4. if ( !myStateMachine )
    5. QwtPlotPicker::transition( pEvent );
    6. else
    7. {
    8. QwtPickerMachine::CommandList commandList =
    9. myStateMachine->transition( *this, pEvent );
    10.  
    11. QPoint pos;
    12. switch( pEvent->type() )
    13. {
    14. case QEvent::MouseButtonDblClick:
    15. case QEvent::MouseButtonPress:
    16. case QEvent::MouseButtonRelease:
    17. case QEvent::MouseMove:
    18. {
    19. pos = ((QMouseEvent *)pEvent)->pos();
    20. break;
    21. }
    22.  
    23. default:
    24. pos = parentWidget()->mapFromGlobal( QCursor::pos() );
    25. break;
    26. }
    27.  
    28. for ( uint i = 0; i < (uint)commandList.count(); i++ )
    29. {
    30. switch( commandList[i] )
    31. {
    32. case QwtPickerMachine::Begin:
    33. {
    34. begin();
    35. break;
    36. }
    37.  
    38. case QwtPickerMachine::Append:
    39. {
    40. append( pos );
    41. break;
    42. }
    43.  
    44. case QwtPickerMachine::Move:
    45. {
    46. QwtPlotPicker::move( pos );
    47. break;
    48. }
    49.  
    50. case QwtPickerMachine::End:
    51. {
    52. end();
    53. break;
    54. }
    55. }
    56. }
    57. }
    58. }
    To copy to clipboard, switch view to plain text mode 

    Sorry for the long answer. Like many things in Qwt, it takes a while to figure out what is going on inside, but when you do you realize that it is a very powerful design and the changes needed to do something special aren't so hard.

    I went through this whole thing last week to implement a custom zoomer that would duplicate the behaviour of an ActiveX control I am replacing with QwtPlot. My zoomer needs to zoom in x only with left-click-drag, zoom out with left-click-only, select a range with right-click-drag, or display a context menu with right-click-delay. It took a few days to get it right, but now the behaviour matches perfectly.
    Hope this helps.

  3. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,781
    Thanks
    262
    Thanked 773 Times in 763 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: How to change the mouse pattern of QwtPlotPicker?

    I realized there are a couple of errors in the code I posted. In the two case statements, if the mouse button press doesn't match the mouse pattern, then they get thrown away. This is wrong; the event should be passed up to the base class for it to handle instead. So, fix the code in both places by adding this:

    Qt Code:
    1. QwtPickerMachine::CommandList MyQwtPickerMachine::transition( const QwtEventPattern & eventPattern, const QEvent * pEvent )
    2. {
    3. QwtPickerMachine::CommandList cmdList;
    4.  
    5. switch( pEvent->type() )
    6. {
    7. case QEvent::MouseButtonPress:
    8. {
    9. if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, (const QMouseEvent *)pEvent ) )
    10. {
    11. //... same as original code
    12. }
    13. else // These two lines are new; add the same thing to the double-click case
    14. cmdList = QwtPickerClickPointMachine::transition( eventPattern, pEvent );
    15. }
    16. break;
    17.  
    18. default:
    19. cmdList = QwtPickerClickPointMachine::transition( eventPattern, pEvent );
    20. break;
    21. }
    22. return cmdList;
    23. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Replies: 4
    Last Post: 27th November 2009, 09:59
  2. Replies: 1
    Last Post: 16th July 2009, 17:58
  3. Replies: 1
    Last Post: 10th July 2009, 10:54
  4. QwtPlotPicker questions
    By ttvo in forum Qwt
    Replies: 7
    Last Post: 28th February 2009, 10:44
  5. Replies: 1
    Last Post: 5th August 2008, 20:36

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.