Update scene



  • Hello. How I can make an Update of the scene? What i mean is... for example I have a scene with drawn rectangles(all red color), and I want them to change color during the execution and compare them if one rectangle(it height number) is lower than the other one I want to swap places. How I can do that?


  • Qt Champions 2017

    Hi
    The QGraphicsItems in the scene has a setPos function
    you can use to move them around.



  • @mrjj and can I change the color of a rectangle during runtime? for example, I have a rectangle which is red and after 5 second it dynamically becomes blue


  • Qt Champions 2017

    Yes, it should be possible.
    How do you make it red in first place?

    Maybe via
    item->setBrush(QBrush(Qt::green));



  • @mrjj I'm trying to make an animation of the bubble sort algorithm, it starts that the first two rectangles are set as green(start point), and I was wondering how I can change the color of the third rectangle to animate the movement?

    #include <QThread>
    #define RANDOM_MAX 100
    #define QUANTITY_RANDOM_NUM 10
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    error = new QErrorMessage(this);
    random_numbers_.clear();
    user_input_numbers_.clear();

    scene = new QGraphicsScene(this);
    ui->graphicsView_animation->setScene(scene);
    for(int i=0;i<QUANTITY_RANDOM_NUM;i++){
    random_numbers_.push_back(rand()%RANDOM_MAX);
    }
    ui->graphicsView_animation->setAlignment(Qt::AlignBottom| Qt::AlignRight);
    QBrush darkMagentaBrush(Qt::darkMagenta);
    QBrush greenBrush(Qt::green);
    QPen Pen(Qt::black);
    Pen.setWidth(2);
    // painter.drawText(temp);
    for(int i=0;i<random_numbers_.size();i++){
    QGraphicsRectItem temp = new QGraphicsRectItem(20+(i30),0-random_numbers_[i],28,random_numbers_[i]);
    temp->setPen(Pen);
    temp->setBrush(darkMagentaBrush);
    rectan.append(temp);
    }
    rectan[0]->setBrush(greenBrush);
    rectan[1]->setBrush(greenBrush);
    for(int i=0;i<random_numbers_.size();i++){
    scene->addItem(rectan.at(i));
    }
    //Bubble implement

    //for(int i=0;i<random_numbers_.size();i++){
    // scene->addRect(20+(i*30),0-random_numbers_[i],28,random_numbers_[i],Pen,darkMagentaBrush);
    //}

    }


  • Qt Champions 2017

    Hi
    You must keep a list or use the build in list to get the items.
    http://doc.qt.io/qt-5.5/qgraphicsscene.html#items
    Then you can change color or move them around.

    U seem to have list already ? rectan



  • @mrjj and how I can swap places the rectangle? I found smth like an Update function but I can't implement it


  • Qt Champions 2017

    @mandruk1331
    But what u want to swap them?
    Is it not enough to just swap the colors?

    QPointF Pos1;
    Pos1=rectan[0]->pos();
    QPointF Pos2;
    Pos2=rectan[1]->pos();
    rectan[0]->setPos(pos2);
    rectan[1]->setPos(pos1);



  • @mrjj No luck, it does not change the position


  • Qt Champions 2017

    @mandruk1331

    Ok.
    So what happened?
    if you do
    rectan[0]->setPos(0,0);

    Does it move then?



  • @mrjj No, at the moment I'm trying to make smth like an Update func

    void MainWindow::Shot(){

    QGraphicsRectItem *Pos1;
    

    Pos1=rectan[0];
    QGraphicsRectItem *Pos2;
    Pos2=rectan[1];
    scene->removeItem(rectan.at(0));
    scene->removeItem(rectan.at(1));

    rectan.at(0) = Pos2;
    rectan.at(1) = Pos1;
    scene->addItem(rectan.at(0));
    scene->addItem(rectan.at(1));
    }


  • Qt Champions 2017

    Hi
    at returns const.
    This looks strange to me
    rectan.at(0) = Pos2;
    maybe
    rectan[0] = Pos2

    Also this will just swap the position in your list.
    It will NOT change on screen.

    You need to use pos() and SetPos
    Not just swap in you array. You swap pointers.
    You should swap QPointF using pos and setPos;



  • @mrjj I thought it will repaint the rects, because first I delete them and then I want to repaint them with new options


  • Qt Champions 2017

    @mandruk1331

    Yes I guess it will repaint them on scene.
    But it matters not for scene if you swap your own array.
    The items still have same location as before as you do not setPos
    (from code shown)



  • @mrjj and another one, I have a loop inside of a loop and when the second one finishes its iteration it won't singleshot on another iteration of the first loop

    for (int =0;i<10;i++){
    //and when i is 1 the second loop won't singleshot again
    for(int j=0;j<9;j++){
    SingleShot
    }
    }


  • Qt Champions 2017

    well
    Normally it works as many times as u set it up but hard to guess at with
    only "SingleShot".



  • @mrjj Why this code does not add the item, I don't understand, I remove it and then I want to re-add it with new options
    void MainWindow::Shot(){
    QGraphicsRectItem *t = new QGraphicsRectItem(rectan.at(0));

    scene->removeItem(rectan.at(1));

    rectan[1] = t;
    scene->addItem(rectan[1]);
    }


  • Qt Champions 2017

    @mandruk1331 said:

    Why do yo u give rectan.at(0) to constructor ?
    new QGraphicsRectItem(rectan.at(0));

    Try
    scene->addItem( new QGraphicsRectItem );
    and tell if that not add a new item?



  • @mrjj Ok, I managed to swap positions of the rectangles, but they swap not always, at first execution they swap on the other they don't, what could be the problem??

    void MainWindow::Shot(){
    QPointF Pos1;
    QPointF Pos2;
    Pos1 = rectan.at(5)->pos();
    Pos2 = rectan.at(6)->pos();

    rectan.at(6)->setBrush(Qt::blue);
    rectan.at(5)->setBrush(Qt::green);
    // rectan.at(5)->setBrush(Qt::blue);
    rectan.at(6)->setPos(Pos1.rx()-30,Pos1.ry());
    rectan.at(5)->setPos(Pos2.rx()+30,Pos2.ry());

    }
    Solved it)


  • Qt Champions 2017

    hi
    put qDebug() << "in shot:"
    in the
    MainWindow::Shot()
    to make sure its actually called mutiple times.



  • @mrjj Pos2 = rectan.at(6)->scenePos(); - this one return (0,0), why? I tried pos() too


  • Qt Champions 2017

    if pos() returns 0,0 , it must mean the items is actually at 0,0.



  • @mrjj and the other ones return 0,0. The object are unique they are all parents and have no child, I want to get the positions of each object so I could move them


  • Qt Champions 2017

    @mandruk1331
    Something is not right.
    Unless they are all really drawn at 0,0 then pos() should return the
    actual position.
    Did you new a QGraphicsRectItem and inserted directly in the list?



  • @mrjj yes, and in the constructor I have set theirs poistions


  • Qt Champions 2017

    Ok, then they should still have the pos, unless you swapped with a
    item having 0,0.


  • Qt Champions 2017

    Can I ask how any values (rects) you try to visualize?



  • @mrjj 10


  • Qt Champions 2017

    @mandruk1331
    ok.
    And did you write the sort also?



  • @mrjj yes
    for( int i=0;i<random_numbers_.size()-1;i++){
    for(int j=0;j<random_numbers_.size()-1;j++){

           if(random_numbers_[j]>random_numbers_[j+1]){
               count++;
    

    QTimer::singleShot(1000*count, [=]{ MainWindow::Shot(j);});

            }
        }
    }

  • Qt Champions 2017

    ok.
    Don't really look like bubble sort.
    :)


  • Qt Champions 2017

    Hi
    I made a half assed bubble sort visualization using
    widget painting.

    2 things wrong with it.
    The actual sort should rather be able to single step but instead
    I use a delay function to slow down drawing. (not pretty)
    So consider it concept rather than good practice.

    That said, its meant for inspiration for your project.

    https://www.dropbox.com/s/ob3x0uvdtbio942/bsort.zip?dl=0



  • @mrjj Thanks a lot,really:-)



  • I know I'm late to the party, but for what it's worth:

    1. There is rarely ever a need to manually update the GraphicsScene. It will automatically update parts whenever you move items (setPos), or change properties of ready-to-use items such as QGraphicsRectItem
    2. If you implement your own item and your own paint method, naturally the scene cannot know which properties will affect the paint and which won't. Therefore, you just call update() on the item after you changed any properties that affect the way the item looks
    3. If you change the boundingRect(), don't forget to call prepareGeometryChange(), otherwise you will have nasty painting effects
    4. Re sorting: qSort, anyone?

Log in to reply
 

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