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. Need to modify a QList item, can List::operator[](int i) do it or is there something better?
Forum Updated to NodeBB v4.3 + New Features

Need to modify a QList item, can List::operator[](int i) do it or is there something better?

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 4.7k Views 1 Watching
  • 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.
  • B Offline
    B Offline
    buckler
    wrote on last edited by
    #1

    Hello,
    I need to find and then modify an item in a list. I understand that "at" doesn't allow this, it uses the copy-write method instead of allowing modification. So I cam across the operator[] function which seems to describe what I want, but I am not getting the results insofar as allowing modification of the original item. Here's my function:
    void cap::logUpdate(QString step, int sessionItemIndex)
    {
    QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
    workItemListEntry wi;
    for (int i=0; i < workItemListPtr->size(); i++) {
    if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
    wi = workItemListPtr->operator;
    break;
    }
    }
    wi.logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
    }

    (Note, that use of the "Ptr" for the list wasn't where I started and may not be helping, in debugging I added this in the event that the list itself was blocking the modification.)

    Here's my class (shortened from my real one so that it isn't to hard to review. It is the "updates" element that I'm trying to effect:
    class workItemListEntry
    {

    public:
    QList<workItemUpdate> updates;
    seriesSurvey *survey;
    int sessionItemIndex;

    workItemListEntry() {};

    void setSessionItemIndex(int index) { sessionItemIndex = index; }

    void setAge(QString str) { age = str; };
    const QString getAge() const { return age; };

    const QList<workItemUpdate> &getWorkItemUpdates() const;
    void setUpdates(const QList<workItemUpdate> &workItemUpdates) { updates = workItemUpdates; };

    void logWorkItemListEntryUpdate(QString step, QWidget *parent);

    private:
    QString age;
    };

    Last but not least, here is the member function being called:
    void workItemListEntry::logWorkItemListEntryUpdate(QString step, QWidget *parent) {
    QString name = getUserName();
    QString str = getISODateTime();
    this->updates.append(workItemUpdate(step, name, str));
    this->unsavedChanges = true;
    ((workItem *)parent)->logListProvenanceUpdate();
    }

    Anyone see my problem?
    Thank you,
    Andy

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      hi
      code a bit hard to read when not formatted.

      you need to use &, i think

      struct workItemUpdate {
        int val;
      };
        workItemUpdate a;
        a.val = 100;
        QList<workItemUpdate> updates;
        updates.append(a);
         workItemUpdate& out = updates[0];
        out.val = 200;
        qDebug() << updates.at(0).val;
      `
      outputs 200
      B 1 Reply Last reply
      0
      • mrjjM mrjj

        hi
        code a bit hard to read when not formatted.

        you need to use &, i think

        struct workItemUpdate {
          int val;
        };
          workItemUpdate a;
          a.val = 100;
          QList<workItemUpdate> updates;
          updates.append(a);
           workItemUpdate& out = updates[0];
          out.val = 200;
          qDebug() << updates.at(0).val;
        `
        outputs 200
        B Offline
        B Offline
        buckler
        wrote on last edited by
        #3

        @mrjj Thank you; but in fact the actual update routine works when called from within the class, by another class member function. The problem occurs, when calling it from a function which is not a member of the class. Specifically, the logging function is a member of class "workItemListEntry", but in this case the function is called from a function in the class "cap". This might help expose the error - since it suggests something across class boundaries being the cause, rather than the function itself, which works as long as called within the class?

        mrjjM 1 Reply Last reply
        0
        • B buckler

          @mrjj Thank you; but in fact the actual update routine works when called from within the class, by another class member function. The problem occurs, when calling it from a function which is not a member of the class. Specifically, the logging function is a member of class "workItemListEntry", but in this case the function is called from a function in the class "cap". This might help expose the error - since it suggests something across class boundaries being the cause, rather than the function itself, which works as long as called within the class?

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @buckler
          well it should not matter if used across classes, (in same app)
          but depends on how you transfer the list or give access to the list ?

          You might make copy of list, if not careful.

          Try to transfer as * to list to be sure. & should also be good but * makes it hard
          to make copy as then normally "= " would just copy pointer, not whole list.
          So for test, use pointer to see if thats the case.

          1 Reply Last reply
          0
          • B Offline
            B Offline
            buckler
            wrote on last edited by SGaist
            #5

            I am using pointer explicitly at the higher level workItemListPtr, and the point of using "operator[]" is to do this for an indiivdual QList item? (QList documentation reads "Returns the item at index position i as a modifiable reference. i must be a valid index position in the list (i.e., 0 <= i < size())."

            The problematic function is (with more care to the formatting, as I agree with you that it is impossible to read otherwise):

            void cap::logUpdate(QString step, int sessionItemIndex)
            {
                 QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
                workItemListEntry wi;
                for (int i=0; i < workItemListPtr->size(); i++) {
                    if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
                        wi = workItemListPtr->operator;
                        break;
                    } // end-if
                } // end-for
                wi.logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
            }
            

            [edit: added missing coding tags ``` SGaist]

            mrjjM 1 Reply Last reply
            0
            • B buckler

              I am using pointer explicitly at the higher level workItemListPtr, and the point of using "operator[]" is to do this for an indiivdual QList item? (QList documentation reads "Returns the item at index position i as a modifiable reference. i must be a valid index position in the list (i.e., 0 <= i < size())."

              The problematic function is (with more care to the formatting, as I agree with you that it is impossible to read otherwise):

              void cap::logUpdate(QString step, int sessionItemIndex)
              {
                   QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
                  workItemListEntry wi;
                  for (int i=0; i < workItemListPtr->size(); i++) {
                      if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
                          wi = workItemListPtr->operator;
                          break;
                      } // end-if
                  } // end-for
                  wi.logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
              }
              

              [edit: added missing coding tags ``` SGaist]

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #6

              @buckler
              Ok so workItemListPtr(); does return pointer to list.
              Next question.
              is
              workItemListEntry wi;
              the item you change?
              Should it not be workItemListEntry &wi;
              as not to get copy ?

              also syntax for pointer to list to avoid the operator syntax is
              (*workItemListPtr)[i];
              You might have reason for operator so just a note.

              1 Reply Last reply
              0
              • B Offline
                B Offline
                buckler
                wrote on last edited by SGaist
                #7

                I have tried a number of variations - including what you suggested as well as a form from another post, presently I have (with no improvement):

                void cap::logUpdate(QString step, int sessionItemIndex) 
                {
                  QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
                  auto& wi = workItemListPtr->operator[](0);
                  for (int i=0; i < workItemListPtr->size(); i++) {
                    if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
                      wi = workItemListPtr->operator[](i);
                      break;
                    }
                  }
                  wi.logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
                }
                

                I did add in a qDebug inside my logging function itself. I print out the actual address when it logs an update. In fact the pointer values are different when it works (i.e., the case of calling it from another function of the same class) vs. when it doesn't work (when calling it from the different class). Clearly, my attempt at pointing to the same memory isn't working.

                [edit: Added missing coding tags ``` SGaist]

                jsulmJ 1 Reply Last reply
                0
                • mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  ok that does sound a bit strange
                  If it possible you make copy of any other object along the way so you indirectly get new list that way?

                  Like insert into other list that makes copy. ?
                  QList<workItemUpdate> updates; this will be copies.

                  Unless across process boundaries and dlls I have never had such issues.
                  It must be something simple or very hard to detect.

                  1 Reply Last reply
                  0
                  • B buckler

                    I have tried a number of variations - including what you suggested as well as a form from another post, presently I have (with no improvement):

                    void cap::logUpdate(QString step, int sessionItemIndex) 
                    {
                      QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
                      auto& wi = workItemListPtr->operator[](0);
                      for (int i=0; i < workItemListPtr->size(); i++) {
                        if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
                          wi = workItemListPtr->operator[](i);
                          break;
                        }
                      }
                      wi.logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
                    }
                    

                    I did add in a qDebug inside my logging function itself. I print out the actual address when it logs an update. In fact the pointer values are different when it works (i.e., the case of calling it from another function of the same class) vs. when it doesn't work (when calling it from the different class). Clearly, my attempt at pointing to the same memory isn't working.

                    [edit: Added missing coding tags ``` SGaist]

                    jsulmJ Online
                    jsulmJ Online
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by jsulm
                    #9

                    @buckler Use a pointer:

                    void cap::logUpdate(QString step, int sessionItemIndex) 
                    {
                      QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
                      workItemListEntry* wi = Q_NULLPTR;
                      for (int i=0; i < workItemListPtr->size(); i++) {
                        if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
                          wi = &((*workItemListPtr)[i]);
                          break;
                        }
                      }
                      if (wi != Q_NULLPTR)
                          wi->logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
                    }
                    

                    And there is no need to call operator[](...) like you do, just use []

                    https://forum.qt.io/topic/113070/qt-code-of-conduct

                    B 1 Reply Last reply
                    1
                    • jsulmJ jsulm

                      @buckler Use a pointer:

                      void cap::logUpdate(QString step, int sessionItemIndex) 
                      {
                        QList<workItemListEntry> *workItemListPtr = sessionItems[sessionItemIndex].select->workItemListPtr();
                        workItemListEntry* wi = Q_NULLPTR;
                        for (int i=0; i < workItemListPtr->size(); i++) {
                          if (workItemListPtr->at(i).survey == sessionItems[sessionItemIndex].survey) {
                            wi = &((*workItemListPtr)[i]);
                            break;
                          }
                        }
                        if (wi != Q_NULLPTR)
                            wi->logWorkItemListEntryUpdate(step, sessionItems[sessionItemIndex].select);
                      }
                      

                      And there is no need to call operator[](...) like you do, just use []

                      B Offline
                      B Offline
                      buckler
                      wrote on last edited by
                      #10

                      @jsulm Thank you! That did it! It is updating nicely now.

                      jsulmJ 1 Reply Last reply
                      0
                      • B buckler

                        @jsulm Thank you! That did it! It is updating nicely now.

                        jsulmJ Online
                        jsulmJ Online
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @buckler Glad to hear it works now :-)

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        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