Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QTableView move rows and update model



  • Hi all,
    With the following code, I can move the position of the lines in my QTableView

    void Gestione::show_item()
    {
      model = new QSqlTableModel(this);
      model->setTable("item");
      model->setHeaderData(1, Qt::Horizontal, tr("Number"));
      model->setHeaderData(2, Qt::Horizontal, tr("Name"));
      model->setHeaderData(3, Qt::Horizontal, tr("Email"));
      if (model->select())
        {
          ui->view_relatori->setModel(model);
          ui->view_relatori->resizeColumnsToContents();
          ui->view_relatori->verticalHeader()->setSectionsMovable(true);
          ui->view_relatori->verticalHeader()->setDragDropOverwriteMode(true);
          ui->view_relatori->verticalHeader()->setDragEnabled(true);
          ui->view_relatori->verticalHeader()->setDragDropMode(QAbstractItemView::InternalMove);
        }
    }
    

    Once I have ordered the list to my liking, I need to save the new order in the database table.
    I tried to read the data with a for loop, but I read from the model and not from the view

    void Gestione::read_data()
    {
      QStringList value_id;
      QStringList value_number;
      QVector<QStringList> current_order;
      current_order.clear();
      for(int i = 0; i < model->rowCount(); i++)
        {
          QSqlRecord record = model->record(i);
          value_id.append(record.value(0).toString());
          value_turno.append(record.value(1).toString());
          row = ui->view->verticalHeader()->visualIndex(i);
        }
      current_order.append(value_id_rel); // 00 List id_rel[]
      current_order.append(value_turno);  // 01 List Number[]
    }
    

    I searched for a solution, but found nothing.
    Is there a method to save the reordered view on the model?
    Thank you in advance
    blackout69


  • Lifetime Qt Champion

    Hi,

    Do you mean you want to be able to change the order of the database fields based on the visual changes you applied to the QTableView ?



  • @sgaist said in QTableView move rows and update model:

    Do you mean you want to be able to change the order of the database fields based on the visual changes you applied to the QTableView ?

    Hi,
    Yes. The number field in the table serves as a "work shift". By changing the order in the view, I would like to update the table number field based on the new order. So that by applying a filter to the number field, I can always have the correct order in the view.

    blackout69



  • @blackout69
    Since you are reordering via moving headers, you should perhaps read the answer in https://stackoverflow.com/questions/41807590/reading-qtableview-row-contents-with-the-same-order-as-are-seen-not-stored. Or, I think @VRonin's answer at https://forum.qt.io/topic/75393/reading-qtableview-row-contents-with-the-same-order-as-are-seen-not-stored/9 addresses your situation.

    Unless I am missing something (I am interested now), it does seems surprisingly complex to read table view row/columns in visual order instead of model order?



  • If you don't use the header to hide individual rows, you could try

    QObject::connect(ui->view_relatori->verticalHeader(),&QHeaderView::sectionMoved,[=](int logicalIndex, int oldVisualIndex, int newVisualIndex)->void{
    Q_ASSERT(logicalIndex==oldVisualIndex);
    const QModelIndex numberIndex =model->index(1,logicalIndex); /*I use 1 here because of model->setHeaderData(1, Qt::Horizontal, tr("Number")); it looks strange, however, you have nothing at index 0*/
    Q_ASSERT(logicalIndex==numberIndex.data().toInt());
    model->setData(numberIndex,newVisualIndex);
    });
    


  • @jonb
    reading based on the view would be great, but I don't know how. Could you tell me how?
    blackout69



  • @vronin

    I get this when I move a row

    ASSERT: "logicalIndex==numberIndex.data().toInt()" in file gestione.cpp, line 843
    Invalid parameter passed to C runtime function.

    /I use 1 here because of model->setHeaderData(1, Qt::Horizontal, tr("Number")); it looks strange, however, you have nothing at index 0/
    My index 0 is the table id
    blackout69



  • @blackout69 said in QTableView move rows and update model:

    My index 0 is the table id

    could you qDebug() << logicalIndex <<"!=" << numberIndex.data().toInt(); and post the result?



  • @VRonin

    QObject::connect(ui->view_relatori->verticalHeader(),&QHeaderView::sectionMoved,[=](int logicalIndex, int oldVisualIndex, int newVisualIndex)->void{
    Q_ASSERT(logicalIndex == oldVisualIndex);
    const QModelIndex numberIndex = relatori_model->index(rel_id_rel,logicalIndex); /*I use 1 here because of model->setHeaderData(1, Qt::Horizontal, tr("Number")); it looks strange, however, you have nothing at index 0*/
    qDebug() << logicalIndex <<"!=" << numberIndex.data().toInt();
    Q_ASSERT(logicalIndex == numberIndex.data().toInt());
    relatori_model->setData(numberIndex,newVisualIndex);
    });
    

    5 != 0
    ASSERT: "logicalIndex == numberIndex.data().toInt()" in file gestione.cpp, line 844
    Invalid parameter passed to C runtime function.
    Invalid parameter passed to C runtime function.

    blackout69



  • @blackout69 said in QTableView move rows and update model:

    The number field in the table serves as a "work shift"

    Looks like it contains a 0 though. what is in that column



  • @vronin said in QTableView move rows and update model:

    Looks like it contains a 0 though. what is in that column

    In that column there is the table id. So only integers starting from 1
    The table is thus formed:
    id_rel int(11)
    turno decimal(3,1)
    name varchar(40)
    email varchar(60)

    blackout69



  • @vronin
    Perfect so it works.
    Thanks for your help.

          QObject::connect(ui->view_relatori->verticalHeader(), &QHeaderView::sectionMoved, [=](int logicalIndex, int oldVisualIndex, int newVisualIndex)->void{
          Q_ASSERT(logicalIndex == oldVisualIndex);
          QModelIndex numberIndex = relatori_model->index(logicalIndex, rel_turno);
          Q_ASSERT(logicalIndex == numberIndex.data().toInt() - 1);
          relatori_model->setData(numberIndex, newVisualIndex + 1);
          relatori_model->submitAll();
          });
    

    blackout69


Log in to reply