Results 1 to 4 of 4

Thread: QGraphicsView move item issues.

  1. #1

    Question QGraphicsView move item issues.

    Hello,

    I am new to deveopment with Qt and are currently developing a simple application which let's you create graphical representation of a scene (e.g. a room) with a transmitter and several sensors. I use the QGraphics framework for this task. The "scene edge" is represented by a class derived from QGraphicsRectItem. The transmitter class is derived from QGraphicsEllipseItem and the sensors are derived from QGraphicsPolygonItem. All these objects and the QGraphicsView/QGraphicsScene are part of the UIInputSceneWidget.

    I was at a point where I was able to move items separately. I.e. the item under the mouse cursor was moved, when you click, hold and move. But now that I moved a few functions around it doesn't work any more and I cannot figure out why.

    There are two possibilities what happens:

    1. If I move the scene edge (QGraphicsRectItem) before adding the transmitter or the sensors, then this rectangle is moved wherever I click, hold and move in the QGraphicsView. The rectangle "jumps" under the cursor as soon as I move the mouse. Even if I click outside the rectangle this happens.

    2. If I do not move the rectangle before adding the transmitter or the sensors, then I can only move the first item that I added (either the transmitter or the first sensor). This item also "jumps" under the cursor as soon as I click, hold and move on a point in the view.

    Here is the code that I suppose is relevant. Please ask for more if this is not sufficient:

    Qt Code:
    1. class UIInputSceneWidget : public QWidget
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. [...]
    7. signals:
    8. [...]
    9. private slots:
    10. void insertFinished();
    11. void insertSceneEdge(UISceneEdge *newSceneEdge);
    12. void insertSensor(QGraphicsSceneMouseEvent *mouseEvent);
    13. void insertTransmitter(QGraphicsSceneMouseEvent *mouseEvent);
    14. [...]
    15.  
    16. private:
    17. UIGraphicsScene *scene;
    18. UIGraphicsView *view;
    19.  
    20. UISceneEdge *sceneEdge;
    21. UITransmitter *transmitter;
    22. QVector<UISensor *> sensors;
    23. [...]
    24. };
    25.  
    26. void UIInputSceneWidget::insertFinished()
    27. {
    28. if (scene->getMode() == UIGraphicsScene::InsertEdge)
    29. scene->setMode(UIGraphicsScene::MoveItem);
    30. }
    31.  
    32. void UIInputSceneWidget::insertSceneEdge(UISceneEdge *newSceneEdge)
    33. {
    34. if (sceneEdge == NULL) {
    35. sceneEdge = newSceneEdge;
    36. } else {
    37. delete newSceneEdge;
    38. return;
    39. }
    40. // stuff regarding buttons which is not important here
    41. }
    42.  
    43. void UIInputSceneWidget::insertSensor(QGraphicsSceneMouseEvent *mouseEvent)
    44. {
    45. if ((sceneEdge == NULL) || !(sceneEdge->pointIsInsideSceneEdge(mouseEvent->scenePos())))
    46. return;
    47.  
    48. UISensor *newSensor = new UISensor(mouseEvent->scenePos(), sceneEdge);
    49. sensors.push_back(newSensor);
    50.  
    51. QString str;
    52. str.setNum(sensors.size());
    53. sensorLineEdit->setText(str);
    54. }
    55.  
    56. void UIInputSceneWidget::insertTransmitter(QGraphicsSceneMouseEvent *mouseEvent)
    57. {
    58. if ((sceneEdge == NULL) || !(sceneEdge->pointIsInsideSceneEdge(mouseEvent->scenePos())))
    59. return;
    60.  
    61. UITransmitter *newTransmitter = new UITransmitter(mouseEvent->scenePos(), sceneEdge);
    62. transmitter = newTransmitter;
    63.  
    64. transmitterButton->setChecked(false);
    65. transmitterButton->setEnabled(false);
    66. scene->setMode(UIGraphicsScene::MoveItem);
    67. setTransmitterLocationLabel();
    68. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. class UIGraphicsScene : public QGraphicsScene
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. enum Mode { InsertEdge, InsertTransmitter, InsertSensor, MoveItem };
    7. void setMode(Mode mode);
    8. [...]
    9.  
    10. signals:
    11. void insertFinished();
    12. void insertSceneEdge(UISceneEdge *sceneEdge);
    13. void insertSensor(QGraphicsSceneMouseEvent *mouseEvent);
    14. void insertTransmitter(QGraphicsSceneMouseEvent *mouseEvent);
    15. [...]
    16.  
    17. protected:
    18. void drawBackground(QPainter *painter, const QRectF &rect);
    19. void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
    20. void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
    21. void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
    22.  
    23. private:
    24. Mode myMode;
    25. QPointF firstPointOfSceneEdge;
    26. };
    27.  
    28. void UIGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
    29. {
    30. if (myMode == InsertEdge) {
    31. qreal x1 = firstPointOfSceneEdge.x();
    32. qreal x2 = mouseEvent->scenePos().x();
    33. qreal y1 = firstPointOfSceneEdge.y();
    34. qreal y2 = mouseEvent->scenePos().y();
    35. QPointF topLeft;
    36. QPointF bottomRight;
    37.  
    38. if (x1 < x2) {
    39. topLeft.setX(x1);
    40. bottomRight.setX(x2);
    41. } else {
    42. topLeft.setX(x2);
    43. bottomRight.setX(x1);
    44. }
    45.  
    46. if (y1 < y2) {
    47. topLeft.setY(y1);
    48. bottomRight.setY(y2);
    49. } else {
    50. topLeft.setY(y2);
    51. bottomRight.setY(y1);
    52. }
    53.  
    54. emit setSceneSize(QRectF(topLeft, bottomRight));
    55. } else if (myMode == MoveItem) {
    56. QGraphicsScene::mouseMoveEvent(mouseEvent);
    57. emit moveEvent(); /* for updating labels and stuff */
    58. }
    59. }
    60.  
    61. void UIGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
    62. {
    63. if (mouseEvent->button() != Qt::LeftButton)
    64. return;
    65.  
    66. switch (myMode) {
    67. case InsertEdge: {
    68. firstPointOfSceneEdge = mouseEvent->scenePos();
    69. UISceneEdge *sceneEdge = new UISceneEdge(QRectF(firstPointOfSceneEdge,
    70. firstPointOfSceneEdge));
    71. addItem(sceneEdge);
    72. emit insertSceneEdge(sceneEdge);
    73. emit setSceneSize(QRectF(firstPointOfSceneEdge,
    74. firstPointOfSceneEdge));
    75. break;
    76. }
    77. case InsertSensor: {
    78. /* The sensor cannot be inserted directly because the pointer to
    79.   * the sceneEdge is not stored in this object, but in
    80.   * UIInputWidget. Let that object create and add the sensor. */
    81. emit insertSensor(mouseEvent);
    82. break;
    83. }
    84. case InsertTransmitter: {
    85. /* Same reason as above! */
    86. emit insertTransmitter(mouseEvent);
    87. break;
    88. }
    89. default:
    90. ;
    91. }
    92. QGraphicsScene::mousePressEvent(mouseEvent);
    93. }
    94.  
    95. void UIGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
    96. {
    97. emit insertFinished();
    98. }
    To copy to clipboard, switch view to plain text mode 

    UIGraphicsView is derived from QGraphicsView and just reimplements keyPressEvent(), wheelEvent() and scaleView(). Nothing special there...

    A screenshot showing the application is attached. This might help you understand the situation.

    I really don't know what happens... Please help me.

    Regards,

    Markus

    EDIT: It might not be clear enough what I want: I want that the item under the mouse cursor moves. If it is the transmitter, then the transmitter should move. If it is a sensor then the sensor should move. If the rectangle is below the cursor then, the rectangle and it's children should move.
    Attached Images Attached Images

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: QGraphicsView move item issues.

    Use the following flags on your items:
    QGraphicsItem::ItemIsMovable
    QGraphicsItem::ItemIsSelectable (if needed)
    QGraphicsItem::ItemSendsGeometryChanges

    More flags:
    http://doc.qt.nokia.com/4.6/qgraphic...sItemFlag-enum

    QGraphicsView lets you move items out of the box, you don't need to add code for that. You only need to add code to handle the items in detail, like what to do when selecting an item or what happens if you move the item.

  3. #3

    Default Re: QGraphicsView move item issues.

    Thank you for the answer. Unfortunately it does not solve my problem. ItemIsMovable was already set to true.

    Setting ItemIsSelectable and ItemSendsGeometryChanges to true does not change much: It is only shown that the item I can move (the same items I could move before) are now selected. I cannot "unselect" this item or select another one.

  4. #4

    Default Re: QGraphicsView move item issues.

    I found the reason for the behaviour: In UIGraphicsScene::mouseReleaseEvent I forgot to pass the mouseEvent on to QGraphicsScene::mouseReleaseEvent:

    Qt Code:
    1. void UIGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
    2. {
    3. emit insertFinished();
    4. QGraphicsScene::mouseReleaseEvent(mouseEvent);
    5. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. scale a QGraphicsView, and it's issues..
    By been_1990 in forum Qt Programming
    Replies: 7
    Last Post: 14th November 2016, 21:25
  2. I hope to move the slider bar in QGraphicsView automatically
    By learning_qt in forum Qt Programming
    Replies: 1
    Last Post: 21st November 2008, 15:35
  3. how to move item up and down in QListView
    By zhanglr in forum Qt Programming
    Replies: 3
    Last Post: 1st August 2008, 15:39
  4. How to move an item on a GraphicsScene
    By Holy in forum Qt Programming
    Replies: 17
    Last Post: 25th July 2008, 15:40
  5. QGraphicsView animation issues?
    By m41n1 in forum Qt Programming
    Replies: 2
    Last Post: 6th June 2008, 08:48

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.