Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Invalid QVariants in a for loop when iterating a QTableView / QStandardItemModel
QtWS25 Last Chance

Invalid QVariants in a for loop when iterating a QTableView / QStandardItemModel

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 1.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fs_tigre
    wrote on last edited by
    #1

    Hi,

    I'm iterating through the content in a QTableView / QStandardItemModel as soon as the program starts to removed any row where the date is less or equal equal to currentDate, everything seems to be working fine except that there is something I cannot understand why which in reality is not creating any problems I just don't understand it.

    Here is the function:

    @void MainWindow::checkIfCurrentDateExistsInTableView()
    {
    int row = model->rowCount();

    for (int i = 0; i < row ; ++i)
    {
            QVariant content = model->data(model->index(i, 0), Qt::DisplayRole); // date
    
            qDebug()<< "content" << content;
    
            QString dateAsQString = content.toString();// get date as string
            QDate qDateFromRows = QDate::fromString(dateAsQString, "ddd MMM dd yyyy");// convert string date to QDate
    
            if(qDateFromRows <= QDate::currentDate())
            {
                model->removeRow(i);
            }
    }
    

    }@

    Now lets pretend that there are three dates that are smaller than currentDate and the function runs, it removes the dates but for some reason and this is where I'm confused is the fact that the for loop continues for a few more cycles after all of the rows have been removed.

    Here is the output:
    @content QVariant(QString, "Sun Sep 01 2013")
    content QVariant(QString, "Mon Sep 02 2013")
    content QVariant(QString, "Tue Sep 03 2013")

    content QVariant(Invalid) // this is what I dont know understand
    content QVariant(Invalid) // this is what I dont know understand
    content QVariant(Invalid) // this is what I dont know understand@

    Can someone be so kind and explain why the Invalid QVariant?

    Thanks

    1 Reply Last reply
    0
    • C Offline
      C Offline
      chris17
      wrote on last edited by
      #2

      I guess the problem here is that the rowCount changes within the loop (removeRow). A easy trick to avoid this is to iterate backwards.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fs_tigre
        wrote on last edited by
        #3

        Thank you for your replay.

        What do you mean by iterate backwards? Can you explain this a little bit?

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          Simple. You're using this loop:
          @
          for (int i = 0; i < row ; ++i) { ... }
          @

          That means, you start at index 0, and increase it with every iteration. Instead, try this:

          @
          for (int i = row - 1; i >= 0 ; --i) { ... }
          @
          Now you start at the last row in your table, and end at the first row.

          Because removing rows affect the row numbers after the current index, you run into problems iterating forward. After removing, the index of the last row is no longer row, but row - 1. After removing the item that you wanted to iterate over next as the row number of the item you just removed! You could compensate your forward loop for that, but that is a bit tricky and frankly quite ugly. But iterating backwards is always fine: even if you removed the current row, the rows before this row are not affected at all.

          Note that your old program doesn't work properly either. What happens if two items next to each other need to be removed?

          Edit: fixed start backwards iteration at row -1 instead of row

          1 Reply Last reply
          0
          • F Offline
            F Offline
            fs_tigre
            wrote on last edited by
            #5

            Thank you both for your help, iterating this way solved the problem, the only thing I had to change is I subtracted 1 to the total number of row because of the way arrays are counted. The first iteration was coming as an invalid QVariant.

            @ int row = model->rowCount();
            row = row - 1;// remove one to the total number of rows
            for (int i = row; i >= 0 ; --i)@

            @Ander
            Note that your old program doesn’t work properly either. What happens if two items next to each other need to be removed?

            I have tried this in a lot different ways and everything seems to be working fine, it removes any row if it is smaller or equal to current date regardless of its position and leaves any date that doesn't meet that criteria.

            Off topic question:
            Are you planning on updating QTimeSpan to work in Qt5 anytime soon?

            Thanks

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              Yes, true, you need to start iterating from row-1. Corrected in previous post.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved