npatil15
4th January 2019, 11:13
Design:
Here I have design a graph where I can plot some signals like oscilloscope. Now I need two vertical and two horizontal lines on the graph which can move vertically and horizontally and also show cross points(symbol) when any signals get cross this lines.
PlotterWidget::PlotterWidget(QWidget *parent)
: QGraphicsView( parent ),
layout(new QVBoxLayout(this)), plot(new QwtPlot()), legend(new QwtLegend()),
m_zoomP(new PlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft, plot->canvas()))
{
layout->setAlignment(plot->canvas(), Qt::AlignTop);
layout->setSizeConstraint(QLayout::SetDefaultConstraint);
plot->setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
layout->addWidget(plot);
plot->plotLayout()->setAlignCanvasToScales(true);//update on crossing the graph
m_zoomM[0] = new QwtPlotMagnifier(plot->canvas()); // ( void ) new QwtPlotMagnifier( canvas );
m_zoomM[0]->setWheelModifiers(Qt::NoModifier); //Scroll --> Both Axis
m_zoomM[1] = new QwtPlotMagnifier(plot->canvas());
m_zoomM[1]->setWheelModifiers(Qt::ControlModifier); //Ctrl + Scroll --> on X-axis
m_zoomM[1]->setAxisEnabled(Qt::XAxis,false);
QWidget *horizontalLineWidget = new QWidget(plot->canvas());
horizontalLineWidget->setFixedHeight(2);
horizontalLineWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
horizontalLineWidget->setStyleSheet(QString("background-color: #c0c0c0;"));
QwtPlotGrid *grid = new QwtPlotGrid();
grid->setPen(QPen(Qt::gray, 0.0, Qt::SolidLine));
grid->enableX(true);
grid->enableXMin(true);
grid->enableY(true);
grid->enableYMin(true);
grid->attach(plot);
legend->setDefaultItemMode(QwtLegendData::Checkable);
QwtSymbol *sym=new QwtSymbol(QwtSymbol::Diamond,QBrush(Qt::red),QPen( Qt::red),QSize(5,5));
d_marker1 = new QwtPlotMarker();
d_marker1->setSymbol(sym);
d_marker1->setLegendIconSize(QSize(20,30));
d_marker1->setLabel(QwtText("VLine1"));
d_marker1->setRenderHint(QwtPlotItem::RenderHint::RenderAntia liased);
d_marker1->setTitle(QwtText("VLine1"));
d_marker1->setLabelOrientation(Qt::Vertical);
d_marker1->setValue(333, 0);
d_marker1->setLineStyle(QwtPlotMarker::VLine);
d_marker1->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
d_marker1->setLinePen(QPen(Qt::blue, 1, Qt::DashDotLine));
d_marker1->setItemAttribute( QwtPlotItem::Legend, true);
d_marker1->attach(plot);
d_marker2 = new QwtPlotMarker();
d_marker2->setSymbol(sym);
d_marker2->setValue(0, 333);
d_marker2->setLabel(QwtText("HLine1"));
d_marker2->setLineStyle(QwtPlotMarker::HLine);
d_marker2->setTitle(QwtText("HLine1"));
d_marker2->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
d_marker2->setLinePen(QPen(Qt::blue, 1, Qt::DashDotLine));
d_marker2->attach(plot);
d_picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
plot->canvas());
d_picker1 = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
plot->canvas());
d_picker->setStateMachine(new QwtPickerDragPointMachine);
d_picker1->setStateMachine(new QwtPickerClickPointMachine);
d_picker->setRubberBandPen(QColor(Qt::green));
d_picker->setTrackerPen(QColor(Qt::blue));
d_picker->setEnabled(true);
connect(d_picker1, SIGNAL(selected(const QPointF &)),
SLOT(selected(const QPointF &)));
plot->setFocusProxy(plot->canvas());
plot->setFocusPolicy(Qt::StrongFocus);
plot->setFocus();
plot->installEventFilter(this);
plot->setAutoReplot(true);
setScaleType("Auto");
plot->insertLegend(legend, QwtPlot::RightLegend );
plot->replot();
connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ), SLOT( &Input::legendChecked( const QVariant &, bool ) ) );
}
And to pick the Line I have write below code
void PlotterWidget::selected(const QPointF &pos)
{
qDebug()<<"selected";
const QwtPlotItemList& items = plot->itemList();
QMetaObject MetaObject = this->staticMetaObject;
QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator ("MarkLine"));
for ( QwtPlotItemIterator i = items.begin(); i != items.end(); ++i )
{
if ( (*i)->rtti() == QwtPlotItem::Rtti_PlotMarker )
{
m_mark = static_cast<QwtPlotMarker*>(*i);
if(!m_mark->isVisible())
{
continue;
}
if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= 5 || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=5)
{
setLineMarker(static_cast<MarkLine>(MetaEnum.keysToValue(m_mark->label().text().toLatin1())));
switch(getLineMarker())
{
case VLine1:
d_marker1->setLinePen(QPen(Qt::blue, 3, Qt::SolidLine));
break;
case HLine1:
d_marker2->setLinePen(QPen(Qt::blue, 3, Qt::SolidLine));
break;
};
connect(d_picker, SIGNAL(moved(const QPoint &)),
SLOT(moved(const QPoint &)));
}
}
}
}
Problem:
I can able to pick line on grid when its of size x(0-1000) and y(0-1000), but the problem is when I'm trying to zoom in/out too much then I cant able to pass this below IF statement properly, because the distance is too less to pick Line.
if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= 5 || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=5)
Need solution how to pick this line properly without affecting zooming the graph ?
It is possible during Zooming, make QwtPlotMarker not get move along with the grid or not zoomed?
And also while zooming, QwtPlotMarker Line get hidden somewhere and difficult to find, so how to deal with this ?
I really get stuck in this, please show me the way.
Thanks a lot for reading this post.
Here I have design a graph where I can plot some signals like oscilloscope. Now I need two vertical and two horizontal lines on the graph which can move vertically and horizontally and also show cross points(symbol) when any signals get cross this lines.
PlotterWidget::PlotterWidget(QWidget *parent)
: QGraphicsView( parent ),
layout(new QVBoxLayout(this)), plot(new QwtPlot()), legend(new QwtLegend()),
m_zoomP(new PlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft, plot->canvas()))
{
layout->setAlignment(plot->canvas(), Qt::AlignTop);
layout->setSizeConstraint(QLayout::SetDefaultConstraint);
plot->setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
layout->addWidget(plot);
plot->plotLayout()->setAlignCanvasToScales(true);//update on crossing the graph
m_zoomM[0] = new QwtPlotMagnifier(plot->canvas()); // ( void ) new QwtPlotMagnifier( canvas );
m_zoomM[0]->setWheelModifiers(Qt::NoModifier); //Scroll --> Both Axis
m_zoomM[1] = new QwtPlotMagnifier(plot->canvas());
m_zoomM[1]->setWheelModifiers(Qt::ControlModifier); //Ctrl + Scroll --> on X-axis
m_zoomM[1]->setAxisEnabled(Qt::XAxis,false);
QWidget *horizontalLineWidget = new QWidget(plot->canvas());
horizontalLineWidget->setFixedHeight(2);
horizontalLineWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
horizontalLineWidget->setStyleSheet(QString("background-color: #c0c0c0;"));
QwtPlotGrid *grid = new QwtPlotGrid();
grid->setPen(QPen(Qt::gray, 0.0, Qt::SolidLine));
grid->enableX(true);
grid->enableXMin(true);
grid->enableY(true);
grid->enableYMin(true);
grid->attach(plot);
legend->setDefaultItemMode(QwtLegendData::Checkable);
QwtSymbol *sym=new QwtSymbol(QwtSymbol::Diamond,QBrush(Qt::red),QPen( Qt::red),QSize(5,5));
d_marker1 = new QwtPlotMarker();
d_marker1->setSymbol(sym);
d_marker1->setLegendIconSize(QSize(20,30));
d_marker1->setLabel(QwtText("VLine1"));
d_marker1->setRenderHint(QwtPlotItem::RenderHint::RenderAntia liased);
d_marker1->setTitle(QwtText("VLine1"));
d_marker1->setLabelOrientation(Qt::Vertical);
d_marker1->setValue(333, 0);
d_marker1->setLineStyle(QwtPlotMarker::VLine);
d_marker1->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
d_marker1->setLinePen(QPen(Qt::blue, 1, Qt::DashDotLine));
d_marker1->setItemAttribute( QwtPlotItem::Legend, true);
d_marker1->attach(plot);
d_marker2 = new QwtPlotMarker();
d_marker2->setSymbol(sym);
d_marker2->setValue(0, 333);
d_marker2->setLabel(QwtText("HLine1"));
d_marker2->setLineStyle(QwtPlotMarker::HLine);
d_marker2->setTitle(QwtText("HLine1"));
d_marker2->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
d_marker2->setLinePen(QPen(Qt::blue, 1, Qt::DashDotLine));
d_marker2->attach(plot);
d_picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
plot->canvas());
d_picker1 = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
plot->canvas());
d_picker->setStateMachine(new QwtPickerDragPointMachine);
d_picker1->setStateMachine(new QwtPickerClickPointMachine);
d_picker->setRubberBandPen(QColor(Qt::green));
d_picker->setTrackerPen(QColor(Qt::blue));
d_picker->setEnabled(true);
connect(d_picker1, SIGNAL(selected(const QPointF &)),
SLOT(selected(const QPointF &)));
plot->setFocusProxy(plot->canvas());
plot->setFocusPolicy(Qt::StrongFocus);
plot->setFocus();
plot->installEventFilter(this);
plot->setAutoReplot(true);
setScaleType("Auto");
plot->insertLegend(legend, QwtPlot::RightLegend );
plot->replot();
connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ), SLOT( &Input::legendChecked( const QVariant &, bool ) ) );
}
And to pick the Line I have write below code
void PlotterWidget::selected(const QPointF &pos)
{
qDebug()<<"selected";
const QwtPlotItemList& items = plot->itemList();
QMetaObject MetaObject = this->staticMetaObject;
QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator ("MarkLine"));
for ( QwtPlotItemIterator i = items.begin(); i != items.end(); ++i )
{
if ( (*i)->rtti() == QwtPlotItem::Rtti_PlotMarker )
{
m_mark = static_cast<QwtPlotMarker*>(*i);
if(!m_mark->isVisible())
{
continue;
}
if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= 5 || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=5)
{
setLineMarker(static_cast<MarkLine>(MetaEnum.keysToValue(m_mark->label().text().toLatin1())));
switch(getLineMarker())
{
case VLine1:
d_marker1->setLinePen(QPen(Qt::blue, 3, Qt::SolidLine));
break;
case HLine1:
d_marker2->setLinePen(QPen(Qt::blue, 3, Qt::SolidLine));
break;
};
connect(d_picker, SIGNAL(moved(const QPoint &)),
SLOT(moved(const QPoint &)));
}
}
}
}
Problem:
I can able to pick line on grid when its of size x(0-1000) and y(0-1000), but the problem is when I'm trying to zoom in/out too much then I cant able to pass this below IF statement properly, because the distance is too less to pick Line.
if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= 5 || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=5)
Need solution how to pick this line properly without affecting zooming the graph ?
It is possible during Zooming, make QwtPlotMarker not get move along with the grid or not zoomed?
And also while zooming, QwtPlotMarker Line get hidden somewhere and difficult to find, so how to deal with this ?
I really get stuck in this, please show me the way.
Thanks a lot for reading this post.