Disappearing QGraphicsObject!



  • Hi guys! :)

    I've lately encountered quite strange problem, mainly:

    • there is a class called "edge" that creates QGraphicsObject - a segment - which endpoints are based on two other QGraphicsObjects positions
    • the boundingRect() is redefined and the resulting bounding rectangle is created from segment endpoints locations
    • the segment is created with:
      painter->drawLine(pstart, pend);
      inside the *paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget widget) function
      Where pstart and pend are QPointF points derived from QGraphiccObjects locations, which are input to the class

    THE PROBLEM

    • when moving the scene by mouse draging or using keys, segments dissapear when some part of them is already behind
      the GraphicsView, seems like the paint function inside the "edge" class is not working at that moment.
      I really do not know what is the problem.

    Any idea what might have gone wrong? :(



  • Maybe a good idea to post some more detailed example ?



  • Yes!

    So this is some of my code.

    The implementation of two classes I use:

    @scene = new QGraphicsScene(this);

    ui->graphicsView->setScene(scene);
    ui->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
    ui->graphicsView->setSceneRect(-1500, -1500, 3000, 3000);
    ui->graphicsView->centerOn(QPoint(200,200));@

    Here come my two QGraphical objects (2 rectangles) that are movable
    and its position will decide about the edge/segment position
    @mygi *mg_1 = new mygi();
    mygi *mg_2 = new mygi();

    mg_1->mrect = QRectF(-8,-8,16,16);
    mg_1->setPos(100,400);
    mg_2->mrect = QRectF(-8,-8,16,16);
    mg_2->setPos(300,300);@

    The edge
    @medge_u = new edge(mg_1,mg_2); // the arguments are: start_ob and end_ob@

    Connect edge to the nodes so when they move its endpoints also move
    @medge_u->connect(medge_u->end_ob,SIGNAL(moves(QPointF)), SLOT(setEnd(QPointF)));
    medge_u->connect(medge_u->start_ob,SIGNAL(moves(QPointF)), SLOT(setStart(QPointF)));

    scene->addItem(medge_u);
    scene->addItem(mg_1);
    scene->addItem(mg_2);@

    CLASS edge
    @----------------------------------------------------------------------------
    #ifndef EDGE_H
    #define EDGE_H

    #include "mygi.h"

    #include <QtGui>
    #include <QtCore>
    #include <QtWidgets>
    #include <QPainter>

    class edge :public QGraphicsObject
    {
    Q_OBJECT

    public:
    edge(QWidget *parent=0);
    edge(mygi *sob, mygi *eob);

    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    
    // My own QGraphics objects
    mygi *start_ob;
    mygi *end_ob;
    
    QRectF mrect;
    
    QPointF pstart;
    QPointF pend;
    QColor mcolor;
    int mwidth;
    

    public slots:
    void setEnd(QPointF p);
    void setStart(QPointF p);

    };
    #endif // EDGE_H

    //The constructor for edge:

    edge::edge(mygi *sob, mygi *eob){
    start_ob = sob;
    end_ob = eob;
    pstart = start_ob->pos();
    pend = end_ob->pos();
    mcolor = QColor(100,200,255,200);
    mwidth = 7;
    update();
    }

    QRectF edge::boundingRect() const
    {
    qreal x0, y0, ye, xe;
    x0 = this->pstart.x();
    y0 = this->pstart.y();
    xe = this->pend.x();
    ye = this->pend.y();
    return QRectF(x0,y0,(xe-x0),(ye-y0));
    }

    void edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
    // ---- Paint the line --------
    QBrush brush(Qt::blue);
    QPen pen(mcolor);
    pen.setWidth(mwidth);
    painter->setPen(pen);
    painter->drawLine(pstart, pend);
    }

    void edge::setEnd(QPointF p)
    {
    pend = p;
    qDebug() << "setEnd!!";
    }
    void edge::setStart(QPointF p)
    {
    pstart = p;
    qDebug() << "setStart!!";
    }@

    And as I mentioned earlier in this post the two graphical objects (the nodes) are just my own QGraphical objects that are movable and emit moves(QPointF) signal while moving.
    The weird thing is that the only object that dissapears in some areas is the edge, the nodes are alway visible. I was trying to figure i out for last few hours but with no success :(

    Thanks in advance!



  • Why don't use "QGraphicsItemGroup":http://doc.qt.digia.com/qt/qgraphicsitemgroup.html ?

    bq. The QGraphicsItemGroup class provides a container that treats a group of items as a single item.

    You can simply grouping all items you need and these will be moving together.

    p.s.
    ... if want to create your items grouping logic, check "Canvas Item Groupies":http://doc.qt.digia.com/qq/qq05-canvasitemgrouping.html written for Qt3 but is very simple to adapt to Qt4/Qt5 graphics view framework



  • Thanks cincirin!
    I'll give it a try, but I guess it would not give what I want.
    You see, what I want is not to move the entire edge with the nodes. What I want
    is to drag the nodes connected to the edge endpoints so one of edge endpoints will update its position while node moves.
    And it works, but there are regions in my scene/view where lines loose their visibility.

    @
    // Initial position
    (S)-------------(E)

    // Drag the (E) node
    (S)



    (E)

    // MY PROBLEM
    // Drag scene

      (S)
        
            
        
             (E)
    

    @

    Maybe you know better way of doing this? :)
    PS. I want both the edge and the node to be QObject so they can use SIGNAL-SLOT functionality.



  • Oh, sorry for confusion, I thought you want to move all items.
    Ok in your case than I think "Diagram Scene Example":http://doc.qt.digia.com/qt/graphicsview-diagramscene.html is very good starting point



  • Hi guys! :)

    OK! My code is working now, however I feel that there must be a better way to do the same thing.
    So what have I changed? Well, in my case it was insufficient definition of the bounding rectangle that caused the problem.
    Now it works, but maybe you know a better way? Is it possible to write less code lines to achieve the same result?
    Why bounding rectangle must be positive-direction-oriented (at least in my case it has to)?

    @ if(pstart.x() <= pend.x() && pstart.y() <= pend.y()){
    // -------------------------------
    // (s)----------
    // | |
    // | |
    // | |
    // ----------(e)
    //
    return QRectF(pstart, pend).adjusted(-mwidth, -mwidth, mwidth, mwidth);
    }
    else if(pstart.x() >= pend.x() && pstart.y() <= pend.y()){

        // -------------------------------
        //   ----------(S)
        //   |           |
        //   |           |
        //   |           |
        //   (E)----------
        //
        return QRectF(QPointF(pend.x(), pstart.y()), QPointF(pstart.x(), pend.y())).adjusted(-mwidth, -mwidth, mwidth, mwidth);
    
    }
    else if(pstart.x() <= pend.x() && pstart.y() >= pend.y()){
        // -------------------------------
        //   ----------(e)
        //   |           |
        //   |           |
        //   |           |
        //   (s)----------
        //
        return QRectF(QPointF(pstart.x(), pend.y()), QPointF(pend.x(), pstart.y())).adjusted(-mwidth, -mwidth, mwidth, mwidth);
    }
    else if(pstart.x() >= pend.x() && pstart.y() >= pend.y()) {
        // -------------------------------
        //   (e)----------
        //   |           |
        //   |           |
        //   |           |
        //   ----------(s)
        //
        return QRectF(pend,pstart).adjusted(-mwidth, -mwidth, mwidth, mwidth);
    }
    

    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.