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.
{
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;
}
QwtPickerMachine::CommandList MyQwtPickerMachine::transition( const QwtEventPattern & eventPattern, const QEvent * pEvent )
{
QwtPickerMachine::CommandList cmdList;
switch( pEvent->type() )
{
case QEvent::MouseButtonPress:
{
if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, (const QMouseEvent *)pEvent ) )
{
if ( state() == 0 )
{
cmdList += Begin;
cmdList += Append;
setState(1);
}
else if ( state() == 1 )
{
cmdList += Append;
}
}
}
break;
default:
cmdList = QwtPickerClickPointMachine::transition( eventPattern, pEvent );
break;
}
return cmdList;
}
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:
case QEvent::MouseButtonDblClick: {
{
if ( state() == 1 )
{
cmdList += Append;
cmdList += End;
setState( 0 );
}
}
}
break;
case QEvent::MouseButtonDblClick:
{
if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1, (const QMouseEvent *)pEvent ) )
{
if ( state() == 1 )
{
cmdList += Append;
cmdList += End;
setState( 0 );
}
}
}
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:
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;
}
}
}
}
}
void MyQwtPlotPicker::transition( const QEvent * pEvent )
{
// "myStateMachine" is an instance of MyQwtPickerMachine
if ( !myStateMachine )
QwtPlotPicker::transition( pEvent );
else
{
QwtPickerMachine::CommandList commandList =
myStateMachine->transition( *this, pEvent );
QPoint pos;
switch( pEvent->type() )
{
case QEvent::MouseButtonDblClick:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
{
pos = ((QMouseEvent *)pEvent)->pos();
break;
}
default:
pos = parentWidget()->mapFromGlobal( QCursor::pos() );
break;
}
for ( uint i = 0; i < (uint)commandList.count(); i++ )
{
switch( commandList[i] )
{
case QwtPickerMachine::Begin:
{
begin();
break;
}
case QwtPickerMachine::Append:
{
append( pos );
break;
}
case QwtPickerMachine::Move:
{
QwtPlotPicker::move( pos );
break;
}
case QwtPickerMachine::End:
{
end();
break;
}
}
}
}
}
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.
Bookmarks