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~
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.
Code:
{
switch( pEvent->type() )
{
case QEvent::MouseButtonPress: {
{
if ( state() == 0 )
{
cmdList += Begin;
cmdList += Append;
setState(1);
}
else if ( state() == 1 )
{
cmdList += Append;
}
}
}
break;
default:
break;
}
return cmdList;
}
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:
Code:
case QEvent::MouseButtonDblClick: {
{
if ( state() == 1 )
{
cmdList += Append;
cmdList += End;
setState( 0 );
}
}
}
break;
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:
Code:
void MyQwtPlotPicker
::transition( const QEvent * pEvent
) {
// "myStateMachine" is an instance of MyQwtPickerMachine
if ( !myStateMachine )
else
{
myStateMachine->transition( *this, pEvent );
switch( pEvent->type() )
{
case QEvent::MouseButtonDblClick: case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: {
break;
}
default:
pos
= parentWidget
()->mapFromGlobal
( QCursor::pos() );
break;
}
for ( uint i = 0; i < (uint)commandList.count(); i++ )
{
switch( commandList[i] )
{
{
begin();
break;
}
{
append( pos );
break;
}
{
break;
}
{
end();
break;
}
}
}
}
}
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.
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:
Code:
{
switch( pEvent->type() )
{
case QEvent::MouseButtonPress: {
{
//... same as original code
}
else // These two lines are new; add the same thing to the double-click case
}
break;
default:
break;
}
return cmdList;
}