Planned maintenance: From Sunday 8th December 10:00 CET there will be changes to try and solve the caching issues that have been experienced. If anyone has a problem connecting after this period then please PM @AndyS or any of the moderators.

How to swap QGraphicsRectItems on scene(changing theirs position)



  • Hello,
    I'm creating a visualization of sorting algorithms. I've got a vector of QGraphicsRectItems which are columns with different height and the same width, generated on the app start. They are being shuffled and then added to a QGraphicsScene. Class named "algorithms" sort a vector of float values which are use to set a height of columns. On swap - it emits a signal to a main class with two integers, so it looks like this:

    emit comparision(array[first element to swap], array[second element to swap]);
    

    Function(on_comparison) in main class is connected with that signal. Problem appeared when I was trying to swap these 2 elements. I've created a variable to set a n column position to it. After that I was trying to setPos of columns so I did something like:

    void on_comparision(int n, int k)
    {
       auto nColumnPos = columns[n]->pos().x();
       columns[n]->setX(columns[k]->pos().x());
       columns[k]->setX(nColumnPos);
       std::swap(columns[n], columns[k]);
    }
    

    But it doesn't work. Positions are not changing. Furthermore

    qDebug() <<nColumnPos;
    

    shows value = 0.

    I was wondering if my whole program works so I decided to implement 2 sorting algorithms which swap 2 near each other elements and modified on_comparison function to

    columns[n]->setX(columns[n].pos().x() + columnsWidth);
    columns[n]->setX(columns[n].pos().x() - columnsWidth);
    std::swap(columns[n], columns[k]);
    

    It works but doesn't give satisfying result. This function will work only with sorting algorithms that check elements 1 after another eg. bubble sort/cocktail sort. It will not work fine with any other sorting algorithm like Merge sort, or Quicksort.

    I was searching for the answer but didn't find anything helpful.

    source code online:
    source code to download, with .pro, .ui and main.cpp files

    Thank you in advance.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You didn't set the position of your items but only worked with their rectangle property so you can do something like:

    auto nRect = columns[n]->rect();
    auto kRect = columns[k]->rect();
    auto nColumnPos = nRect.left();
    nRect.moveLeft(kRect.left());
    kRect.moveLeft(nColumnPos);
    
    columns[n]->setRect(nRect);
    columns[k]->setRect(kRect);
    std::swap(columns[n], columns[k]);
    
    comparisions++;
    ui->LabelComparisions_var->setNum(comparisions);
    


  • @SGaist Oh that seems pretty obvious, what a shame I did not think about it. Thank you so much for helping me.


  • Lifetime Qt Champion

    You're welcome !

    Since you have it working now, please mark the thread as solved using the "Topic Tools" button so that other forum users may know a solution has been found :)