Results 1 to 12 of 12

Thread: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jun 2015
    Posts
    109
    Thanks
    20
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Question How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    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.

    Qt Code:
    1. PlotterWidget::PlotterWidget(QWidget *parent)
    2. : QGraphicsView( parent ),
    3. layout(new QVBoxLayout(this)), plot(new QwtPlot()), legend(new QwtLegend()),
    4. m_zoomP(new PlotZoomer(QwtPlot::xBottom, QwtPlot::yLeft, plot->canvas()))
    5. {
    6. layout->setAlignment(plot->canvas(), Qt::AlignTop);
    7. layout->setSizeConstraint(QLayout::SetDefaultConstraint);
    8. plot->setSizePolicy(QSizePolicy::Policy::Minimum, QSizePolicy::Policy::Minimum);
    9.  
    10.  
    11. layout->addWidget(plot);
    12.  
    13. plot->plotLayout()->setAlignCanvasToScales(true);//update on crossing the graph
    14.  
    15. m_zoomM[0] = new QwtPlotMagnifier(plot->canvas()); // ( void ) new QwtPlotMagnifier( canvas );
    16. m_zoomM[0]->setWheelModifiers(Qt::NoModifier); //Scroll --> Both Axis
    17.  
    18. m_zoomM[1] = new QwtPlotMagnifier(plot->canvas());
    19. m_zoomM[1]->setWheelModifiers(Qt::ControlModifier); //Ctrl + Scroll --> on X-axis
    20. m_zoomM[1]->setAxisEnabled(Qt::XAxis,false);
    21.  
    22.  
    23. QWidget *horizontalLineWidget = new QWidget(plot->canvas());
    24. horizontalLineWidget->setFixedHeight(2);
    25. horizontalLineWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    26. horizontalLineWidget->setStyleSheet(QString("background-color: #c0c0c0;"));
    27.  
    28. QwtPlotGrid *grid = new QwtPlotGrid();
    29. grid->setPen(QPen(Qt::gray, 0.0, Qt::SolidLine));
    30. grid->enableX(true);
    31. grid->enableXMin(true);
    32. grid->enableY(true);
    33. grid->enableYMin(true);
    34. grid->attach(plot);
    35.  
    36. legend->setDefaultItemMode(QwtLegendData::Checkable);
    37. QwtSymbol *sym=new QwtSymbol(QwtSymbol::Diamond,QBrush(Qt::red),QPen(Qt::red),QSize(5,5));
    38. d_marker1 = new QwtPlotMarker();
    39. d_marker1->setSymbol(sym);
    40. d_marker1->setLegendIconSize(QSize(20,30));
    41. d_marker1->setLabel(QwtText("VLine1"));
    42. d_marker1->setRenderHint(QwtPlotItem::RenderHint::RenderAntialiased);
    43. d_marker1->setTitle(QwtText("VLine1"));
    44. d_marker1->setLabelOrientation(Qt::Vertical);
    45. d_marker1->setValue(333, 0);
    46. d_marker1->setLineStyle(QwtPlotMarker::VLine);
    47. d_marker1->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
    48. d_marker1->setLinePen(QPen(Qt::blue, 1, Qt::DashDotLine));
    49. d_marker1->setItemAttribute( QwtPlotItem::Legend, true);
    50.  
    51. d_marker1->attach(plot);
    52.  
    53. d_marker2 = new QwtPlotMarker();
    54. d_marker2->setSymbol(sym);
    55. d_marker2->setValue(0, 333);
    56. d_marker2->setLabel(QwtText("HLine1"));
    57. d_marker2->setLineStyle(QwtPlotMarker::HLine);
    58. d_marker2->setTitle(QwtText("HLine1"));
    59. d_marker2->setLabelAlignment(Qt::AlignRight | Qt::AlignBottom);
    60. d_marker2->setLinePen(QPen(Qt::blue, 1, Qt::DashDotLine));
    61. d_marker2->attach(plot);
    62.  
    63. d_picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
    64. QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
    65. plot->canvas());
    66. d_picker1 = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
    67. QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
    68. plot->canvas());
    69.  
    70. d_picker->setStateMachine(new QwtPickerDragPointMachine);
    71. d_picker1->setStateMachine(new QwtPickerClickPointMachine);
    72.  
    73. d_picker->setRubberBandPen(QColor(Qt::green));
    74. d_picker->setTrackerPen(QColor(Qt::blue));
    75. d_picker->setEnabled(true);
    76.  
    77. connect(d_picker1, SIGNAL(selected(const QPointF &)),
    78. SLOT(selected(const QPointF &)));
    79.  
    80.  
    81. plot->setFocusProxy(plot->canvas());
    82. plot->setFocusPolicy(Qt::StrongFocus);
    83. plot->setFocus();
    84. plot->installEventFilter(this);
    85.  
    86.  
    87. plot->setAutoReplot(true);
    88. setScaleType("Auto");
    89.  
    90. plot->insertLegend(legend, QwtPlot::RightLegend );
    91. plot->replot();
    92.  
    93. connect( legend, SIGNAL( checked( const QVariant &, bool, int ) ), SLOT( &Input::legendChecked( const QVariant &, bool ) ) );
    94. }
    To copy to clipboard, switch view to plain text mode 

    And to pick the Line I have write below code

    Qt Code:
    1. void PlotterWidget::selected(const QPointF &pos)
    2. {
    3. qDebug()<<"selected";
    4. const QwtPlotItemList& items = plot->itemList();
    5.  
    6. QMetaObject MetaObject = this->staticMetaObject;
    7. QMetaEnum MetaEnum = MetaObject.enumerator(MetaObject.indexOfEnumerator("MarkLine"));
    8.  
    9. for ( QwtPlotItemIterator i = items.begin(); i != items.end(); ++i )
    10. {
    11. if ( (*i)->rtti() == QwtPlotItem::Rtti_PlotMarker )
    12. {
    13. m_mark = static_cast<QwtPlotMarker*>(*i);
    14. if(!m_mark->isVisible())
    15. {
    16. continue;
    17. }
    18. if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= 5 || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=5)
    19. {
    20. setLineMarker(static_cast<MarkLine>(MetaEnum.keysToValue(m_mark->label().text().toLatin1())));
    21. switch(getLineMarker())
    22. {
    23. case VLine1:
    24. d_marker1->setLinePen(QPen(Qt::blue, 3, Qt::SolidLine));
    25. break;
    26. case HLine1:
    27. d_marker2->setLinePen(QPen(Qt::blue, 3, Qt::SolidLine));
    28. break;
    29. };
    30. connect(d_picker, SIGNAL(moved(const QPoint &)),
    31. SLOT(moved(const QPoint &)));
    32. }
    33. }
    34. }
    35. }
    To copy to clipboard, switch view to plain text mode 


    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.
    Qt Code:
    1. if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= 5 || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=5)
    To copy to clipboard, switch view to plain text mode 

    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.

  2. #2
    Join Date
    Jun 2015
    Posts
    109
    Thanks
    20
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    I have added event filter which identify the wheel up/down and based on that I have manage to increase the 5 using setting variable m_pickPoint in the event and it work for normal condition.
    Qt Code:
    1. if (sqrt( pow( (m_mark->xValue() - pos.x()), 2 )) <= m_pickPoint || sqrt( pow( (m_mark->yValue() - pos.y()), 2 )) <=m_pickPoint )
    To copy to clipboard, switch view to plain text mode 

    So here I'm unable to understand at what factor I should increase or decrease the value m_pickPoint, so that the above logic work properly and pick the exact line.
    Qt Code:
    1. case QEvent::Wheel:
    2. QWheelEvent* we = static_cast<QWheelEvent*>(e);
    3. if(we->angleDelta().y()>0)
    4. {
    5. m_pickPoint = m_pickPoint + m_pickPoint*0.05;
    6. qDebug()<<"Position"<<m_pickPoint;
    7. }
    8. else
    9. {
    10. m_pickPoint = m_pickPoint - m_pickPoint*0.05;
    11. qDebug()<<"Negative"<<m_pickPoint;
    12. }
    To copy to clipboard, switch view to plain text mode 

    Please provide your solution, where as this above solution looks kind of dirty, so if their is some elegant solution then please suggest.
    Last edited by npatil15; 8th January 2019 at 11:32.

  3. #3
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,278
    Thanked 872 Times in 820 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    You have to translate the coordinates of your marker and the mouse click into widget coordinates. See https://qwt.sourceforge.io/class_qwt...3d2ce46507b865

    Uwe

  4. #4
    Join Date
    Jun 2015
    Posts
    109
    Thanks
    20
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    Hi,

    Thanks for the reply,

    I have no trouble while catching/translating exact coordinates on the plot/widget. The problem is when I zoom in/out, the IF logic doen't work properly because I cant handle the m_pickPoint, which help me get the closet area to pick the QwtPlotMarker line. So looking for a solution how do I pick a line with such solution which doesn't affect on zoom in/out.

    Or is their a easiest way, that I can create a line widget and simply do drag and drop event. I have tried the same but dont know how to handle it, because I just want to drag to vertically or horizontally only not other way.

  5. #5
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,278
    Thanked 872 Times in 820 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    The zoomer installs an event filter for the plot canvas to handle the mouse events. In general it is possible to install as many events filters as you like - they are processed in reverse order of how they have been installed until one of them returns true.
    So you can simply install your own event filter - or create a QwtPicker/QwtPlotPicker - after attaching the zoomer.

    Uwe

  6. #6
    Join Date
    Jun 2015
    Posts
    109
    Thanks
    20
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    I have implement the eventfilter attached to zoomer which detect mouseevent and using this I can drag and drop the line on the graph.
    Also based on the zoom level I have manipulate the QwtPlotPicker to pick the line properly. But the way I implement is not picking the line properly when the zoom level is too deep, so normally it works perfectly.

  7. #7
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,278
    Thanked 872 Times in 820 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    Quote Originally Posted by npatil15 View Post
    I have implement the eventfilter attached to zoomer ...
    I would create an extra QwtPlotPicker for this usecase, where you return false from it eventFilter, when you don't want to forward the event to the zoomer. But this is not necessary to solve your problem.

    But the way I implement is not picking the line properly when the zoom level is too deep, so normally it works perfectly.
    Here we are back to my previous hint. Translate point and marker position into widget coordinates - then you can use a fixed distance in pixels, regardless of the zoom level.

  8. The following user says thank you to Uwe for this useful post:

    npatil15 (10th January 2019)

  9. #8
    Join Date
    Jun 2015
    Posts
    109
    Thanks
    20
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming

    I got your point, and sure this will be the solution if I translate point and marker into widget coordinates.
    But as I'm new for qwt and not sure how to do that. Can you please give me some code snippets or any link which explains about it ?

  10. #9
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,278
    Thanked 872 Times in 820 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to pick line of QwtPlotMarker using QwtPlotPicker without affecting zooming


Similar Threads

  1. Replies: 2
    Last Post: 4th January 2019, 11:14
  2. Replies: 2
    Last Post: 20th July 2015, 06:14
  3. Replies: 2
    Last Post: 26th July 2013, 14:25
  4. QwtPlotMarker QwtPlotPicker
    By bss in forum Qwt
    Replies: 1
    Last Post: 15th June 2011, 12:55

Tags for this Thread

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.