Results 1 to 5 of 5

Thread: QGraphicsItem inheritence

  1. #1
    Join Date
    Apr 2009
    Posts
    17
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QGraphicsItem inheritence

    I need to subclass an existing QGraphicsItem and change the painting
    and size. I started modifying the elasticnodes example and came up with
    these changes:

    Qt Code:
    1. class Node : public QGraphicsItem
    2. {
    3. public:
    4. Node(GraphWidget *graphWidget);
    5.  
    6. void addEdge(Edge *edge);
    7. QList<Edge *> edges() const;
    8.  
    9. enum { Type = UserType + 1 };
    10. int type() const { return Type; }
    11.  
    12. void calculateForces();
    13. bool advance();
    14.  
    15. virtual QRectF boundingRect() const;
    16. QPainterPath shape() const;
    17. virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    18.  
    19. protected:
    20. QVariant itemChange(GraphicsItemChange change, const QVariant &value);
    21.  
    22. virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    23. virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    24.  
    25. QList<Edge *> edgeList;
    26. QPointF newPos;
    27. GraphWidget *graph;
    28.  
    29. private:
    30.  
    31. };
    To copy to clipboard, switch view to plain text mode 

    So for my derived class, I need to make boundingRect(), paint(), and mousePressEvent() virtual, because I want my class to paint a pixmap
    and catch it's own mousePressEvents.
    Correct?

    So I subclassed Node, loaded a rectangular image in the constructor, implemented boundingRect(), paint(), and mousePressEvent(). Compiles and runs ok.
    Just one problem - I can't drag the rectangular image by the mouse!

    Some qDebug statements in the relevant methods shows that the derived class
    is receiving mousePressEvents, but only in the exact area where a Node (ball) would be (around 0,0 in my pixmap). It looks like I need to make another method in Node virtual to override the default area where a Node accepts mouse events.

    I hope this is clear. The attached jpg shows a closeup.
    The white circle is some sort of "ghost" node that will accept a mouse press
    and allow me to drag the pixmap. I can't drag the pixmap anywhere else.

    thanks,
    -baj
    Attached Images Attached Images

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem inheritence

    Quote Originally Posted by bajarangi View Post
    So for my derived class, I need to make boundingRect(), paint(), and mousePressEvent() virtual, because I want my class to paint a pixmap
    and catch it's own mousePressEvents.
    Correct?
    They already are virtual. You just need to reimplement the methods.

    So I subclassed Node, loaded a rectangular image in the constructor, implemented boundingRect(), paint(), and mousePressEvent(). Compiles and runs ok.
    Just one problem - I can't drag the rectangular image by the mouse!
    Call the base class implementation of mousePressEvent() and mouseReleaseEvent() in your reimplementations.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Apr 2009
    Posts
    17
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem inheritence

    Thanks again, Wysotta. Still no joy here.
    So I removed the virtual keywords from the Node class, recompiled and ran. No change.

    Here's the derived class declaration:
    Qt Code:
    1. class CloudNode : public Node
    2. {
    3. public:
    4. CloudNode(GraphWidget *graphWidget);
    5.  
    6. protected:
    7. void paint( QPainter *, const QStyleOptionGraphicsItem *option, QWidget *widget );
    8. QRectF boundingRect() const;
    9. void mousePressEvent(QGraphicsSceneMouseEvent *event);
    10. void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    11.  
    12. private:
    13. QImage *cloudimage;
    14. QPixmap pixmap;
    15. };
    16.  
    17. CloudNode::CloudNode(GraphWidget *graphWidget) : Node(graphWidget)
    18. {
    19. qDebug() << "Creating CloudNode";
    20. cloudimage = new QImage(); // = new QImage();
    21. bool loadsuccess = cloudimage->load("./images/background.png");
    22. qDebug() << "CloudNode loaded image = " << loadsuccess;
    23. setFlag(ItemIsMovable);
    24. setCacheMode(DeviceCoordinateCache);
    25. pixmap = QPixmap::fromImage(*cloudimage, Qt::OrderedAlphaDither);
    26. }
    27.  
    28.  
    29. void CloudNode::paint( QPainter *p, const QStyleOptionGraphicsItem *option, QWidget * )
    30. {
    31. qDebug() << "CloudNode::paint";
    32. p->drawPixmap(0, 0, pixmap);
    33. }
    34.  
    35. QRectF CloudNode::boundingRect() const
    36. {
    37. int adjust = 0;
    38. QRectF noderect(-adjust, -adjust, cloudimage->width() +10, cloudimage->height()+10);
    39. //qDebug() << "CloudNode width " << noderect.width() << " height " << noderect.height();
    40. return noderect;
    41. }
    42.  
    43. void CloudNode::mousePressEvent(QGraphicsSceneMouseEvent *event)
    44. {
    45. update();
    46. QGraphicsItem::mousePressEvent(event);
    47. qDebug() << "CloudNode mouse x " << event->pos().x() << " y " << event->pos().y();
    48. }
    To copy to clipboard, switch view to plain text mode 

    Problem persists as before. I can click and drag the pixmap in a small area around
    0,0 and qDebug output shows:
    CloudNode mouse x 2.64032 y 0.489026
    But I don't receive the mouse click anywhere else in the pixmap.

    Do I have to re-implement itemChange() ? I wouldn't think so, that only
    is called after the mouse event is received.

    In Graphwidget constructor I have this for a CloudNode:
    CloudNode *cnode8 = new CloudNode(this);
    scene->addItem(cnode8);
    scene->addItem(new Edge(cnode8, node7));
    cnode8->setPos(150, 150);

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem inheritence

    I'd guess your boundingRect() or shape() implementation is incorrect. Try reimplementing shape() to return the result of boundingRect() and see if it changes anything.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. The following user says thank you to wysota for this useful post:

    bajarangi (12th August 2009)

  6. #5
    Join Date
    Apr 2009
    Posts
    17
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11

    Smile Re: QGraphicsItem inheritence

    SUCCESS!

    Yea, the runtime was defaulting to the Node implementation of shape(), which
    was an elipse around 0,0. Reiplemented shape() in CloudNode like:

    Qt Code:
    1. QPainterPath CloudNode::shape() const
    2. {
    3. path.addRect(0, 0, cloudimage->width(), cloudimage->height());
    4. return path;
    5. }
    To copy to clipboard, switch view to plain text mode 

    and I can now drag the pixmap from any point in the rectangle.

    Thanks again.
    -baj
    Last edited by wysota; 12th August 2009 at 00:48. Reason: missing [code] tags

Similar Threads

  1. Replies: 2
    Last Post: 25th March 2011, 09:18
  2. destruction of QGraphicsItem
    By killkolor in forum Qt Programming
    Replies: 2
    Last Post: 5th December 2009, 10:31
  3. Replies: 1
    Last Post: 25th February 2009, 00:34
  4. QGraphicsItem does not update
    By zgulser in forum Qt Programming
    Replies: 1
    Last Post: 5th February 2009, 14:44
  5. Snap-to grid on QGraphicsItem
    By hardgeus in forum Qt Programming
    Replies: 9
    Last Post: 28th April 2008, 16:22

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.