I have got the following problem:
If I drag only one item, then in "cursorMoved" function, I just set the mouseposition to the item's position and it works fine. If I select several items and want to drag them, then they get all the mouse position and appears at the same place. How can I implement such movement that the selected items only moves relatively to mouse direction and movement? Can you provide me a code snippet of it? I thought about storing the initial mouse click position and calculate the difference relatively to this initial point, but the "cursorMoved" function is called frequently while dragging so that this varaible would be overridden...

my code:
Qt Code:
  1. ...
  2. // create QwtPlotPicker to allow user moving the points on the plot
  3.  
  4. picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
  5. QwtPicker::RectSelection | QwtPicker::DragSelection,
  6. QwtPlotPicker::RectRubberBand, QwtPicker::AlwaysOn,
  7. this->canvas());
  8.  
  9. // connect the signals coming from QwtPlotPicker with the member functions
  10. connect( picker, SIGNAL(moved(const QwtDoublePoint& ) ),
  11. this, SLOT(cursorMoved( const QwtDoublePoint& ) ) );
  12.  
  13. connect( picker, SIGNAL(selected (const QwtDoubleRect &) ),
  14. this, SLOT(RectangleSelected( const QwtDoubleRect& ) ) );
  15. ...
  16.  
  17. // this function provides the ability to select several items on the plot by dragging a rectangle around them
  18. void Plot::RectangleSelected( const QwtDoubleRect& rect){
  19. std::cout << "in Plot::RectangleSelected" << std::endl;
  20. //============= clear the list with selected items, before start new selection
  21. if(!selected_Points.empty()){
  22. while(!selected_Points.empty()){
  23. QwtPlotMarker *tempMark = selected_Points.back();
  24. const QwtSymbol symbol = tempMark->symbol();
  25. QwtSymbol newSymbol = symbol;
  26. newSymbol.setBrush(symbol.brush().color().light(150)); // turn back the highlighten symbol
  27. tempMark->setSymbol(newSymbol);
  28. selected_Points.pop_back(); // delete the selected items from the list
  29. }
  30. }
  31. //============= end of clear the list
  32.  
  33. const QwtPlotItemList& List = itemList(); // get all items from the plot
  34. QwtPlotItemIterator Iter = List.begin();
  35.  
  36. // get the two vertice of the selection rectangle
  37. QwtDoublePoint tl = rect.topLeft();
  38. QwtDoublePoint br = rect.bottomRight();
  39. std::cout << "recOfClick(x,y,width, height) =" << rect.x()<<", " << rect.y() << ", " << rect.width()<< ", "<<rect.height()<< std::endl;
  40. double TRtlX = this->transform(picker->xAxis(),tl.x()); // transform the rectangles coordinates to plot's coordinates
  41. double TRtlY = this->transform(picker->yAxis(),tl.y());
  42. double TRbrX = this->transform(picker->xAxis(),br.x());
  43. double TRbrY= this->transform(picker->yAxis(),br.y());
  44. QwtDoubleRect *trRect= new QwtDoubleRect(QRect(QPoint(TRtlX,TRtlY),QPoint(TRbrX,TRbrY))); // build a rectangle with the new coordinates
  45. std::cout << "recOfClick(x,y,width, height) =" << trRect->x()<<", " << trRect->y() << ", " << trRect->width()<< ", "<<trRect->height()<< std::endl;
  46. if( trRect->width()<5 && trRect->height()<5){ // if it was just a click and not drugged rectangle, then...
  47. trRect->setHeight(20); // ...generate a rectangle around the click's position
  48. trRect->setWidth(20);
  49.  
  50. }
  51.  
  52. while(Iter != List.end()) // and iterate through them...
  53. {
  54. if((*Iter)->rtti() == QwtPlotItem::Rtti_PlotMarker){ // ... until you find the item from class QwtPLotMarker
  55. QwtPlotMarker *mark = ((QwtPlotMarker*)(*Iter));
  56. double x = this->transform(mark->xAxis(),mark->xValue()); // transform the item's coordinates to plot's coordinates
  57. double y = this->transform(mark->yAxis(),mark->yValue());
  58. std::cout << "mark.xValue()=" << mark->xValue() << ", mark.yValue()=" << mark->yValue()<< std::endl;
  59. std::cout << "transformed mark coord = " << x << ", " << y<< std::endl;
  60. QwtDoublePoint trPoint = QwtDoublePoint(x,y); // create a point consisting of transformed coordinates
  61.  
  62.  
  63. if(trRect->contains(trPoint)){ // if click's rectangle includes the QwtPlotMarker, then...
  64. std::cout << "MATCH" << std::endl;
  65.  
  66. //selectedPoint = mark; // ... save the pointer to this item into variable "selectedPoint"
  67. std::cout << "selectedPoint = " << mark << std::endl;
  68. const QwtSymbol symbol = mark->symbol();
  69. QwtSymbol newSymbol = symbol;
  70. newSymbol.setBrush(symbol.brush().color().dark(150)); // highlighten the selected item by darken its color
  71. mark->setSymbol(newSymbol);
  72. selected_Points.push_back(mark);
  73. }
  74.  
  75. }
  76. Iter++;
  77. }
  78. replot();
  79. std::cout << "selected_Points.size()= " << selected_Points.size() << std::endl;
  80. }
  81. //##################################################################
  82. // this function provides the ability to move items on the plot
  83. void Plot::cursorMoved( const QwtDoublePoint& Point){
  84.  
  85. std::cout << "in Plot::cursorMoved " << std::endl;
  86. std::cout << "Point.x()= " << Point.x() <<"Point.y()= " << Point.y() << std::endl;
  87. if(!selected_Points.empty()){ //if the list with selected items is not empty, then...
  88. for(unsigned i=0; i< selected_Points.size(); ++i) {
  89. std::cout << "loop " << i << std::endl;
  90. selected_Points[i]->setValue(Point); // set the new coordinates to the moved item
  91. }
  92. this->replot(); // replot the plot widget after the selected point was moved
To copy to clipboard, switch view to plain text mode