Hello all,
I started to build application based on stockchart example. Basing on CanvasPicker class I would like to handle mouse moves, forward them by emitting signal to main class and there display selected coordinates and draw lines from it on the chart. It is simple idea of technical analysis above the bar chart. My problem is coordinates are not properly displayed and lets say if I select point and move mouse once on 1.03(x-scale is qwtDate) on the x-scale and then change application window size (it is f.e. maximize) and after that once again move mouse on 1.03 -my cooridnates will be different.
CanvasPicker
::CanvasPicker(QwtPlot *plot
): d_selectedCurve(NULL),
d_selectedPoint(-1)
{
plot->setMouseTracking(true);
QwtPlotCanvas *canvas
= qobject_cast<QwtPlotCanvas
*>
(plot
->canvas
());
canvas->installEventFilter(this);
canvas->setFocusPolicy(Qt::StrongFocus);
canvas->setFocus();
shiftCurveCursor(true);
}
bool CanvasPicker
::event(QEvent *e
) {
if ( e
->type
() == QEvent::User ) {
showCursor(true);
return true;
}
}
{
if ( object
!= (QObject *)plot
()->canvas
() ) return false;
switch(e->type())
{
showCursor(true);
showCursor(false);
{
break;
}
case QEvent::MouseButtonPress: {
return true;
}
{
return true;
}
default:
break;
}
return QObject::eventFilter(object, e
);
}
void CanvasPicker
::select(const QPoint &pos
) {
emit createCurve();
TAcurveDataX[0]=pos.x();
TAcurveDataY[0]=pos.y();
}
void CanvasPicker
::move(const QPoint &pos
) {
TAcurveDataX[1]=pos.x();
TAcurveDataY[1]=pos.y();
emit emitCurve(TAcurveDataX[0],TAcurveDataY[0],TAcurveDataX[1],TAcurveDataY[1]);
}
CanvasPicker::CanvasPicker(QwtPlot *plot):
QObject(plot),
d_selectedCurve(NULL),
d_selectedPoint(-1)
{
plot->setMouseTracking(true);
QwtPlotCanvas *canvas = qobject_cast<QwtPlotCanvas*>(plot->canvas());
canvas->installEventFilter(this);
canvas->setFocusPolicy(Qt::StrongFocus);
canvas->setFocusIndicator(QwtPlotCanvas::ItemFocusIndicator);
canvas->setFocus();
shiftCurveCursor(true);
}
bool CanvasPicker::event(QEvent *e)
{
if ( e->type() == QEvent::User )
{
showCursor(true);
return true;
}
return QObject::event(e);
}
bool CanvasPicker::eventFilter(QObject *object, QEvent *e)
{
if ( object != (QObject *)plot()->canvas() )
return false;
switch(e->type())
{
case QEvent::FocusIn:
showCursor(true);
case QEvent::FocusOut:
showCursor(false);
case QEvent::Paint:
{
QApplication::postEvent(this, new QEvent(QEvent::User));
break;
}
case QEvent::MouseButtonPress:
{
select(((QMouseEvent *)e)->pos());
return true;
}
case QEvent::MouseMove:
{
move(((QMouseEvent *)e)->pos());
return true;
}
default:
break;
}
return QObject::eventFilter(object, e);
}
void CanvasPicker::select(const QPoint &pos)
{
emit createCurve();
TAcurveDataX[0]=pos.x();
TAcurveDataY[0]=pos.y();
}
void CanvasPicker::move(const QPoint &pos)
{
TAcurveDataX[1]=pos.x();
TAcurveDataY[1]=pos.y();
emit emitCurve(TAcurveDataX[0],TAcurveDataY[0],TAcurveDataX[1],TAcurveDataY[1]);
}
To copy to clipboard, switch view to plain text mode
Above is CanvasPicker class, simple idea is to handle mouse click and mouse move to create 2 points -
{TAcurveDataX[0],TAcurveDataY[0]},
{TAcurveDataX[1],TAcurveDataY[1]}.
These points are forwarding into main class.
After create QwtPlotCurve and connect with appropriate slots like below:
d_plot[chartUseNumber] = new Plot( this );
CanvasPicker *pick=new CanvasPicker(d_plot[chartUseNumber]);
connect(pick,SIGNAL(createCurve()),this,SLOT(CreateNewCanvasCurve()));
connect(pick,SIGNAL(emitCurve(double,double,double,double)),this,SLOT(ReceiveCurveData(double,double,double,double)));
d_plot[chartUseNumber] = new Plot( this );
CanvasPicker *pick=new CanvasPicker(d_plot[chartUseNumber]);
connect(pick,SIGNAL(createCurve()),this,SLOT(CreateNewCanvasCurve()));
connect(pick,SIGNAL(emitCurve(double,double,double,double)),this,SLOT(ReceiveCurveData(double,double,double,double)));
To copy to clipboard, switch view to plain text mode
Creating plot:
{
this->setMouseTracking(true);
this->curve=NULL;
QwtDateScaleDraw *scaleDraw = new DateScaleDraw( Qt::UTC );
QwtDateScaleEngine *scaleEngine = new QwtDateScaleEngine( Qt::UTC );
//setAxisTitle( QwtPlot::xBottom, QString( "2010" ) );
setAxisScaleDraw
( QwtPlot::xBottom, scaleDraw
);
setAxisScaleEngine
( QwtPlot::xBottom, scaleEngine
);
setAxisLabelRotation
( QwtPlot::xBottom,
-50.0 );
setAxisLabelAlignment
( QwtPlot::xBottom, Qt
::AlignLeft | Qt
::AlignBottom );
Legend *legend = new Legend;
//insertLegend( legend, QwtPlot::RightLegend );
this->global_sample_count=255;
this->current_instr=0;
panner->setMouseButton( Qt::MidButton );
connect( legend,
SIGNAL( checked
( QwtPlotItem *,
bool,
int ) ),
}
void Plot::populate2(int instrument,int start,int end,int mode)
{
GridItem *gridItem = new GridItem();
gridItem->attach( this );
const Qt::GlobalColor colors[] =
{
Qt::red,
Qt::blue,
Qt::darkCyan,
Qt::darkMagenta,
Qt::darkYellow
};
if(curve!=NULL)
{
delete curve;
}
const int numColors = sizeof( colors ) / sizeof( colors[0] );
if(instrument!=0)
{
QuoteFactory::Stock stock = static_cast<QuoteFactory::Stock>( instrument-1 );
curve = new QwtPlotTradingCurve();
curve->setTitle( QuoteFactory::title( stock ) );
curve->setOrientation( Qt::Vertical );
curve->setSamples( QuoteFactory::samples_fn( stock,start,end,mode ) );
curve->setSymbolExtent( 12 * 3600 * 1000.0 );
curve->setMinSymbolWidth( 3 );
curve->setMaxSymbolWidth( 15 );
const Qt::GlobalColor color = colors[ instrument % numColors ];
curve->setSymbolPen( color );
curve->setSymbolBrush( QwtPlotTradingCurve::Decreasing, color );
curve->setSymbolBrush( QwtPlotTradingCurve::Increasing, Qt::white );
curve->attach( this );
showItem( curve, true );
}
}
Plot::Plot( QWidget *parent ):
QwtPlot( parent )
{
this->setMouseTracking(true);
this->curve=NULL;
QwtDateScaleDraw *scaleDraw = new DateScaleDraw( Qt::UTC );
QwtDateScaleEngine *scaleEngine = new QwtDateScaleEngine( Qt::UTC );
//setAxisTitle( QwtPlot::xBottom, QString( "2010" ) );
setAxisScaleDraw( QwtPlot::xBottom, scaleDraw );
setAxisScaleEngine( QwtPlot::xBottom, scaleEngine );
setAxisLabelRotation( QwtPlot::xBottom, -50.0 );
setAxisLabelAlignment( QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom );
Legend *legend = new Legend;
//insertLegend( legend, QwtPlot::RightLegend );
this->global_sample_count=255;
this->current_instr=0;
QwtPlotPanner *panner = new QwtPlotPanner( canvas() );
panner->setMouseButton( Qt::MidButton );
connect( legend, SIGNAL( checked( QwtPlotItem *, bool, int ) ),
SLOT( showItem( QwtPlotItem *, bool ) ) );
}
void Plot::populate2(int instrument,int start,int end,int mode)
{
GridItem *gridItem = new GridItem();
gridItem->attach( this );
const Qt::GlobalColor colors[] =
{
Qt::red,
Qt::blue,
Qt::darkCyan,
Qt::darkMagenta,
Qt::darkYellow
};
if(curve!=NULL)
{
delete curve;
}
const int numColors = sizeof( colors ) / sizeof( colors[0] );
if(instrument!=0)
{
QuoteFactory::Stock stock = static_cast<QuoteFactory::Stock>( instrument-1 );
curve = new QwtPlotTradingCurve();
curve->setTitle( QuoteFactory::title( stock ) );
curve->setOrientation( Qt::Vertical );
curve->setSamples( QuoteFactory::samples_fn( stock,start,end,mode ) );
curve->setSymbolExtent( 12 * 3600 * 1000.0 );
curve->setMinSymbolWidth( 3 );
curve->setMaxSymbolWidth( 15 );
const Qt::GlobalColor color = colors[ instrument % numColors ];
curve->setSymbolPen( color );
curve->setSymbolBrush( QwtPlotTradingCurve::Decreasing, color );
curve->setSymbolBrush( QwtPlotTradingCurve::Increasing, Qt::white );
curve->attach( this );
showItem( curve, true );
}
}
To copy to clipboard, switch view to plain text mode
I use it in the following way:
void MainWindow::ReceiveCurveData(double x1,double y1,double x2,double y2)
{
yvar=( year2010.addDays( x1 )) ;
ine->setText(yvar.toString());
double arr1[2];
double arr2[2]={(d_plot[0]->invTransform(currvamac->yAxis(), y1)),(d_plot[0]->invTransform(currvamac->yAxis(), y2))};
double arr1o=QwtDate::toDouble(dt1);
double arr2o=QwtDate::toDouble(dt2);
double d1=QwtDate::toDouble( year2010.addDays( x1 )) ;
double d2=QwtDate::toDouble( year2010.addDays( x2 )) ;
arr1[0] = d1;
arr1[1] = d2;
currvamac->setSamples(arr1,arr2,2);
d_plot[0]->replot();
}
void MainWindow::ReceiveCurveData(double x1,double y1,double x2,double y2)
{
QDateTime year2010( QDate( 2010, 1, 1 ), QTime( 0, 0 ), Qt::UTC );
QVariant yvar;
yvar=( year2010.addDays( x1 )) ;
ine->setText(yvar.toString());
double arr1[2];
double arr2[2]={(d_plot[0]->invTransform(currvamac->yAxis(), y1)),(d_plot[0]->invTransform(currvamac->yAxis(), y2))};
QDateTime dt1 = QwtDate::toDateTime(x1);
QDateTime dt2 = QwtDate::toDateTime(x2);
double arr1o=QwtDate::toDouble(dt1);
double arr2o=QwtDate::toDouble(dt2);
double d1=QwtDate::toDouble( year2010.addDays( x1 )) ;
double d2=QwtDate::toDouble( year2010.addDays( x2 )) ;
arr1[0] = d1;
arr1[1] = d2;
currvamac->setSamples(arr1,arr2,2);
d_plot[0]->replot();
}
To copy to clipboard, switch view to plain text mode
There is no problem with y-coordinates, only with x-coordinates. Thanks for help in advance.
Bookmarks