Results 1 to 14 of 14

Thread: Position of QGraphicsItem on Scene.

  1. #1
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Position of QGraphicsItem on Scene.

    Hello,

    im new in progamming wie Qt, so i had try some tutorials.
    One of is:

    http://www.bogotobogo.com/Qt/Qt5_QGr...phicsScene.php

    This is the basic of my code.

    What i want to do:

    On the graphics view i add two ellipse (ellipse1, ellipse2) and a line.

    I change the flags of the ellipses to moveable.

    So now i want that the start point of the line (x1,y2) is on the center of ellipse1 and the end point of the line (x2,y2) is at the center of ellipse2.
    If one ellipse move per mouse, the line should move too.

    If i add the line in this way:
    Qt Code:
    1. line = scene->addLine(ellipse1->scenePos().x(),ellipse1->scenePos().y(),
    2. ellipse2->scenePos().x(),ellipse2->scenePos().y(),outlinePen);
    To copy to clipboard, switch view to plain text mode 

    For the scenPos() function i get 0. But i dont know why.

    Did anyone has an idee ?

    Thx

    dialog.hdialog.cppdialog.hdialog.cpp

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    Derive a custom class from QGraphicsEllipseItem.

    Add a setter method that takes a line element and an indicator to which end of the line your item is connected to.

    Then in the itemChange() method of your item class, you move "your" end of the line when ever the item moves.

    Cheers,
    _

  3. #3
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Position of QGraphicsItem on Scene.

    thx for the answer:

    i had try the modification, on basic of:

    http://www.bogotobogo.com/Qt/Qt5_QGr...phicsItems.php

    A additional class customItem is inherit from QGraphicsItem.

    With this approach i get now the positions on scene from ellipse1 and ellipse2.

    But drawing a line is not possible until now.

    Now there are different options. The line can be member of the Dialog class or is a member of the customItem class.
    For the second option, it should be drawn two lines.
    One from ellipses1 to ellipses2, and one from ellipses2 to ellipses1


    customitem.cppcustomitem.hdialog.cppdialog.h
    Last edited by Andre008; 10th February 2016 at 18:16.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    My suggestion was to use a QGraphicsLineItem and adjusting its end points

    Cheers,
    _

  5. #5
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Position of QGraphicsItem on Scene.

    ok, i had tried it with:

    dialog.cpp
    Here i send the line pointer .

    Qt Code:
    1. Dialog::Dialog(QWidget *parent) :
    2. QDialog(parent),
    3. ui(new Ui::Dialog)
    4. {
    5. ui->setupUi(this);
    6.  
    7.  
    8. scene = new QGraphicsScene(this);
    9. ui->graphicsView->setScene(scene);
    10.  
    11. // create our object and add it to the scene
    12. ellipse1 = new customItem();
    13. ellipse2 = new customItem();
    14. line = new QGraphicsLineItem(100,100,450,300);
    15.  
    16.  
    17. qDebug() << "ellipse1->scenePos().x(): " << ellipse1->scenePos().x();
    18.  
    19. ellipse1->setLine(line,false);
    20. ellipse1->setLine(line,true);
    21.  
    22. scene->addItem(ellipse1);
    23. scene->addItem(ellipse2);
    24. scene->addItem(line);
    25.  
    26. }
    To copy to clipboard, switch view to plain text mode 

    dialog.h
    Qt Code:
    1. class Dialog : public QDialog
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. explicit Dialog(QWidget *parent = 0);
    7. ~Dialog();
    8.  
    9. private:
    10. Ui::Dialog *ui;
    11.  
    12.  
    13. customItem *ellipse1;
    14. customItem *ellipse2;
    15.  
    16.  
    17. };
    18.  
    19. #endif // DIALOG_H
    To copy to clipboard, switch view to plain text mode 


    customItem.cpp

    Qt Code:
    1. void customItem::setLine(QGraphicsLineItem* newLine, bool side)
    2. {
    3. line = newLine;
    4. startOrEnd = side;
    5. }
    6.  
    7. void customItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    8. {
    9. Pressed = false;
    10. update();
    11. QGraphicsItem::mouseReleaseEvent(event);
    12.  
    13. if(startOrEnd == false)
    14. {
    15. line->line().setLine(this->scenePos().x(),this->scenePos().y(),
    16. line->line().x2(),line->line().y2() );
    17. }
    18.  
    19. if(startOrEnd == true)
    20. {
    21. line->line().setLine(line->line().x1(),line->line().y1(),
    22. this->scenePos().x(),this->scenePos().y());
    23.  
    24. }
    25.  
    26. qDebug()<<"xPos: " << this->scenePos().x();
    27. qDebug()<<"yPos: " << this->scenePos().y();
    28. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. class customItem : public QGraphicsItem
    2. {
    3. public:
    4. customItem();
    5. .....
    6.  
    7. void setLine(QGraphicsLineItem line, bool side);
    8.  
    9. .....
    10.  
    11. public:
    12.  
    13. bool Pressed;
    14.  
    15. bool startOrEnd;
    16.  
    17. };
    To copy to clipboard, switch view to plain text mode 

    But it dont work.
    Last edited by Andre008; 10th February 2016 at 23:04.

  6. #6
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    First, I thought you wanted the line to be between the two centers, so why are you using x/y?
    Also why use scenePos() instead of just the position?

    The center would be just
    Qt Code:
    1. QPointF center = rect().center();
    To copy to clipboard, switch view to plain text mode 

    It would also be easier to get the updated position after it has changed, instead of manually reacting to mouse events.

    Cheers,
    _

  7. #7
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Position of QGraphicsItem on Scene.

    youre right:

    i had change it to:

    customItem.cpp
    here ist the member variable for the center: mCenter for the ellipse
    Qt Code:
    1. void customItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    2. {
    3. QRectF ellipse = boundingRect();
    4.  
    5. mCenter = ellipse.center();
    6.  
    7. qDebug() << "mCenter: " << mCenter;
    8.  
    9. if(Pressed)
    10. {
    11. QPen pen(Qt::red, 3);
    12. painter->setPen(pen);
    13. painter->drawEllipse(ellipse);
    14. }
    15. else
    16. {
    17. QPen pen(Qt::black, 3);
    18. painter->setPen(pen);
    19. painter->drawEllipse(ellipse);
    20. }
    21. }
    22.  
    23.  
    24. void customItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    25. {
    26. Pressed = false;
    27.  
    28.  
    29.  
    30. if(startOrEnd == false)
    31. {
    32. line->line().setP1(mCenter);
    33. }
    34.  
    35.  
    36. if(startOrEnd == true)
    37. {
    38. line->line().setP2(mCenter);
    39. }
    40.  
    41.  
    42. update();
    43. QGraphicsItem::mouseReleaseEvent(event);
    44. }
    To copy to clipboard, switch view to plain text mode 

    but the line do not move

  8. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    If look at the method signature of QGraphicsLineItem::line(), which is generally a good idea, you will see that it returns a QLineF object.
    Not a pointer, not a reference, an object.

    You are modifying that object but are not storing or using it in any way.
    So you are modifying a temporary object.

    How would that change anything for the line item?

    Cheers,
    _

  9. #9
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Position of QGraphicsItem on Scene.

    Quote Originally Posted by anda_skoa View Post
    If look at the method signature of QGraphicsLineItem::line(), which is generally a good idea, you will see that it returns a QLineF object.
    Not a pointer, not a reference, an object.

    You are modifying that object but are not storing or using it in any way.
    So you are modifying a temporary object.

    Cheers,
    _
    Ok, now i change the specific parts to QLineF:

    customItem.cpp

    I thought the storing could be made with the function setLine or how can i implement it, to assign a line to an ellipses?.


    Qt Code:
    1. void customItem::setLine(QLineF newLine, bool side)
    2. {
    3. line = newLine;
    4. startOrEnd = side;
    5. }
    6.  
    7. void customItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    8. {
    9. Pressed = false;
    10.  
    11. if(startOrEnd == false)
    12. {
    13. line.setP1(mCenter);
    14. }
    15.  
    16.  
    17. if(startOrEnd == true)
    18. {
    19. line.setP2(mCenter);
    20. }
    21.  
    22. update();
    23. QGraphicsItem::mouseReleaseEvent(event);
    24. }
    To copy to clipboard, switch view to plain text mode 

    customItem.h

    Qt Code:
    1. class customItem : public QGraphicsItem
    2. {
    3. public:
    4. customItem();
    5.  
    6. QRectF boundingRect() const;
    7.  
    8. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    9.  
    10. void mousePressEvent(QGraphicsSceneMouseEvent *event);
    11. void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    12.  
    13. void setLine(QLineF newLine, bool side);
    14.  
    15. qreal getXPosEllipse();
    16. qreal getYPosEllipse();
    17. public:
    18.  
    19. bool Pressed;
    20.  
    21. bool startOrEnd;
    22. //QGraphicsLineItem *line;
    23.  
    24. QLineF line;
    25. QPointF mCenter;
    26. };
    To copy to clipboard, switch view to plain text mode 



    Qt Code:
    1. Dialog::Dialog(QWidget *parent) :
    2. QDialog(parent),
    3. ui(new Ui::Dialog)
    4. {
    5. ui->setupUi(this);
    6.  
    7.  
    8. scene = new QGraphicsScene(this);
    9. ui->graphicsView->setScene(scene);
    10.  
    11. QBrush grayBrush(Qt::gray);
    12. QPen outlinePen(Qt::black);
    13. outlinePen.setWidth(2);
    14.  
    15. // create our object and add it to the scene
    16.  
    17.  
    18. ellipse1 = new customItem();
    19. ellipse2 = new customItem();
    20. line = new QGraphicsLineItem(100,100,450,300);
    21.  
    22. ellipse1->setLine(line->line(),false);
    23. ellipse2->setLine(line->line(),true);
    24.  
    25.  
    26. qDebug() << "ellipse1->getXPosEllipse(): " << ellipse1->getXPosEllipse();
    27. qDebug() << "ellipse1->getYPosEllipse(): " << ellipse1->getYPosEllipse();
    28. scene->addItem(ellipse1);
    29. scene->addItem(ellipse2);
    30. scene->addItem(line);
    31.  
    32.  
    33.  
    34. qDebug() << "ellipse1->getXPosEllipse(): " << ellipse1->getXPosEllipse();
    35. qDebug() << "ellipse1->getYPosEllipse(): " << ellipse1->getYPosEllipse();
    36.  
    37. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    That doesn't even make sense. Now you not even attempting to update the line item anymore.

    The ellipse items need to update the position of the line item, so they need the line item.

    But instead of your previous attempt of changing some random temporary line value, you need to update the line item's value.

    Lets have a look at some C++ basics
    Qt Code:
    1. int a = 5;
    2. int b = a;
    3. b = 3;
    4. // which value does a have?
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  11. #11
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Position of QGraphicsItem on Scene.

    Quote Originally Posted by anda_skoa View Post
    That doesn't even make sense. Now you not even attempting to update the line item anymore.

    The ellipse items need to update the position of the line item, so they need the line item.

    But instead of your previous attempt of changing some random temporary line value, you need to update the line item's value.

    Lets have a look at some C++ basics
    Qt Code:
    1. int a = 5;
    2. int b = a;
    3. b = 3;
    4. // which value does a have?
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _


    My idee was to make something like this:

    Qt Code:
    1. int a=5;
    2. int *b;
    3.  
    4. b= &a;
    5. *b = 3;
    To copy to clipboard, switch view to plain text mode 

    For this reason i create a local variable line in the class custonItem.

  12. #12
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    Yes, your code in comment #7 has the line as a pointer, that is fine.

    But instead of modifying that line, you are modifying an object return by one of its getters, an object that is discarded immediately afterwards (it is a temporary object).

    You write
    Qt Code:
    1. line->line().setP1(mCenter);
    To copy to clipboard, switch view to plain text mode 
    which is equivalent to
    Qt Code:
    1. QLineF a = line->line();
    2. a.setP1(mCenter);
    To copy to clipboard, switch view to plain text mode 
    How do you expect "line" to move when you are not changing its values?

    You need to change the data your "line" has access to, not some copy of that data.

    Cheers,
    _

  13. #13
    Join Date
    Feb 2016
    Posts
    17
    Thanks
    3
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Position of QGraphicsItem on Scene.

    now it runs:

    Thx for your patience anda_skoa

    Here ist the full code:

    dialog.h

    Qt Code:
    1. #include <QDialog>
    2. #include <QGraphicsScene>
    3. #include <QGraphicsView>
    4. #include <QGraphicsItem>
    5. #include <QDebug>
    6.  
    7. #include "customitem.h"
    8.  
    9. namespace Ui {
    10. class Dialog;
    11. }
    12.  
    13. class Dialog : public QDialog
    14. {
    15. Q_OBJECT
    16.  
    17. public:
    18. explicit Dialog(QWidget *parent = 0);
    19. ~Dialog();
    20.  
    21. private:
    22. Ui::Dialog *ui;
    23.  
    24.  
    25. customItem *ellipse1;
    26. customItem *ellipse2;
    27.  
    28.  
    29.  
    30. };
    To copy to clipboard, switch view to plain text mode 

    dialog.cpp

    Qt Code:
    1. Dialog::Dialog(QWidget *parent) :
    2. QDialog(parent),
    3. ui(new Ui::Dialog)
    4. {
    5. ui->setupUi(this);
    6.  
    7.  
    8. scene = new QGraphicsScene(this);
    9. ui->graphicsView->setScene(scene);
    10.  
    11. QBrush grayBrush(Qt::gray);
    12. QPen outlinePen(Qt::black);
    13. outlinePen.setWidth(2);
    14.  
    15.  
    16. ellipse1 = new customItem();
    17. ellipse2 = new customItem();
    18. line = new QGraphicsLineItem(ellipse1->scenePos().x() + ellipse1->mCenter.x(),
    19. ellipse1->scenePos().y() + ellipse1->mCenter.y(),
    20. ellipse2->scenePos().x() + ellipse2->mCenter.x(),
    21. ellipse2->scenePos().y() + ellipse2->mCenter.y());
    22.  
    23. ellipse1->setLine(line,false);
    24. ellipse2->setLine(line, true);
    25.  
    26.  
    27. scene->addItem(ellipse1);
    28. scene->addItem(ellipse2);
    29. scene->addItem(line);
    30. }
    To copy to clipboard, switch view to plain text mode 


    cusomItem.h

    Qt Code:
    1. #include <QPen>
    2. #include <QGraphicsItem>
    3. #include <QPainter>
    4.  
    5. #include <QDebug>
    6.  
    7. class customItem : public QGraphicsItem
    8. {
    9. public:
    10. customItem();
    11.  
    12. QRectF boundingRect() const;
    13.  
    14. void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    15.  
    16. void mousePressEvent(QGraphicsSceneMouseEvent *event);
    17. void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    18.  
    19. void setLine(QGraphicsLineItem *newLine, bool side);
    20.  
    21. qreal getXPosEllipse();
    22. qreal getYPosEllipse();
    23. public:
    24.  
    25. bool Pressed;
    26.  
    27. bool startOrEnd;
    28. QGraphicsLineItem *customLine;
    29.  
    30. QPointF mCenter;
    31. };
    To copy to clipboard, switch view to plain text mode 


    customItem.cpp

    Qt Code:
    1. #include "customitem.h"
    2.  
    3. customItem::customItem()
    4. {
    5. Pressed = false;
    6. setFlag(ItemIsMovable);
    7.  
    8. }
    9.  
    10. QRectF customItem::boundingRect() const
    11. {
    12. // outer most edges
    13. return QRectF(0,0,100,100);
    14. }
    15.  
    16. void customItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    17. {
    18. QRectF ellipse = boundingRect();
    19.  
    20. mCenter = ellipse.center();
    21.  
    22. //qDebug() << "mCenter: " << mCenter;
    23.  
    24. if(Pressed)
    25. {
    26. QPen pen(Qt::red, 3);
    27. painter->setPen(pen);
    28. painter->drawEllipse(ellipse);
    29. }
    30. else
    31. {
    32. QPen pen(Qt::black, 3);
    33. painter->setPen(pen);
    34. painter->drawEllipse(ellipse);
    35. }
    36. }
    37.  
    38.  
    39.  
    40. qreal customItem::getXPosEllipse()
    41. {
    42. return this->scenePos().x();
    43. }
    44. qreal customItem::getYPosEllipse()
    45. {
    46. return this->scenePos().y();
    47. }
    48.  
    49. void customItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
    50. {
    51. Pressed = true;
    52. update();
    53. QGraphicsItem::mousePressEvent(event);
    54.  
    55. }
    56.  
    57. void customItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
    58. {
    59. Pressed = false;
    60.  
    61. if(startOrEnd == false)
    62. {
    63. customLine->setLine( this->scenePos().x() + mCenter.x(),this->scenePos().y()+ mCenter.y(),
    64. customLine->line().x2(), customLine->line().y2() );
    65. }
    66.  
    67.  
    68. if(startOrEnd == true)
    69. {
    70. customLine->setLine( customLine->line().x1(), customLine->line().y1(),
    71. this->scenePos().x() + mCenter.x(),this->scenePos().y()+ mCenter.y());
    72. }
    73.  
    74. update();
    75. QGraphicsItem::mouseReleaseEvent(event);
    76. }
    77.  
    78.  
    79. void customItem::setLine(QGraphicsLineItem *newLine, bool side)
    80. {
    81. qDebug() << "-------------------------------------------";
    82. qDebug() << "&customLine:\t" << &customLine << "\t&newLine:\t" << &newLine;
    83. qDebug() << "customLine:\t" << customLine << "\tnewLine:\t" << newLine;
    84.  
    85. customLine = newLine;
    86. startOrEnd = side;
    87.  
    88. qDebug() << "customLine:\t" << customLine << "\tnewLine:\t" << newLine;
    89. }
    To copy to clipboard, switch view to plain text mode 

  14. #14
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,419
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Position of QGraphicsItem on Scene.

    Just a general suggestion for improvement:
    when you have a toggle state like startOrEnd in your case, using a bool is often not a good way regarding readability.

    I.e. consider reading "startOrEnd == true" in several months, what does "true" mean? An either/or question can usually not be answered with yes/no.

    A way better approach is to use an enum with two values, each value appropriately named

    Qt Code:
    1. enum ManagedLineEnd {
    2. StartOfLine,
    3. EndOfLine
    4. };
    5.  
    6. ManagedLineEnd m_myLineEnd;
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. if (m_myLineEnd == StartOfLine)
    To copy to clipboard, switch view to plain text mode 

    For an example on how that is used in Qt see the two enum arguments of QString::split().

    Cheers,
    _

  15. The following user says thank you to anda_skoa for this useful post:

    Andre008 (24th February 2016)

Similar Threads

  1. Scene Mouse Position Slightly Offline :S
    By steadi in forum Newbie
    Replies: 5
    Last Post: 23rd October 2012, 14:43
  2. QGraphics scene position
    By junix in forum Newbie
    Replies: 6
    Last Post: 17th April 2012, 03:41
  3. Cursor Position in scene
    By rogerholmes in forum Newbie
    Replies: 2
    Last Post: 12th March 2010, 15:31
  4. Replies: 0
    Last Post: 16th July 2009, 12:44
  5. Cursor scene position
    By xgoan in forum Qt Programming
    Replies: 1
    Last Post: 26th December 2006, 13:51

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.