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. QtConcurrent::run and QList<QListWidgetItem*>::Iterator crashes
QtWS25 Last Chance

QtConcurrent::run and QList<QListWidgetItem*>::Iterator crashes

Scheduled Pinned Locked Moved Solved General and Desktop
qtconcurrentqlistiterators
6 Posts 2 Posters 2.4k 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.
  • M Offline
    M Offline
    Max13
    wrote on last edited by
    #1

    I'm on a small app, which fills a QListWidget with newed QListWidgetItems (around 40'000 items) while some of them are stored in a QList<QListWidgetItem*> (almost all of them). All are part of the same class: MainWidget.

    From there, I assumed that the QList pointers are exactely the same as some of the QListWidget's model. Stop me if I'm wrong.

    So based on that, when I click a button, a slot is executed (using QtConcurrent) to toggle the hidden attribute of all the QListWidgetItems contained in the QList<QListWidgetItem*>. Here is the code for toggle:

    void    MainWidget::toggle(void)
    {
        bool    newBool(!(*(this->m_okItems.cbegin() + 1))->isHidden());
    
        for (QList<QListWidgetItem*>::Iterator i(this->m_okItems.begin()); i != this->m_okItems.end(); ++i) {
            (*i)->setHidden(newBool);
        }
    
        this->endLoading();
    }
    

    And here is how I start the it

    QtConcurrent::run(this, &MainWidget::toggle);
    

    The first time I start this, it's OK. All the "hidden" items are shown, and vice-versa. The second time, it crashes during the execution of the QtConcurrent, and the debugger points to the asm instructions (I don't know ASM). I've also tried to put a qDebug() with a counter to see at which point it fails, if it's at the same item or not. It crashes randomly. Sometimes at the 35'000 th iteration, sometimes at 16'000th (rounded).

    I can't see how it could be related to thread safety as I disable the main GUI while the QtConcurrent is running (endLoading() is made to reenable to GUI). What am I missing?

    Thanks for your help.

    We all have started by asking questions. Then after some time, we can begin answering them.

    kshegunovK 1 Reply Last reply
    0
    • M Max13

      I'm on a small app, which fills a QListWidget with newed QListWidgetItems (around 40'000 items) while some of them are stored in a QList<QListWidgetItem*> (almost all of them). All are part of the same class: MainWidget.

      From there, I assumed that the QList pointers are exactely the same as some of the QListWidget's model. Stop me if I'm wrong.

      So based on that, when I click a button, a slot is executed (using QtConcurrent) to toggle the hidden attribute of all the QListWidgetItems contained in the QList<QListWidgetItem*>. Here is the code for toggle:

      void    MainWidget::toggle(void)
      {
          bool    newBool(!(*(this->m_okItems.cbegin() + 1))->isHidden());
      
          for (QList<QListWidgetItem*>::Iterator i(this->m_okItems.begin()); i != this->m_okItems.end(); ++i) {
              (*i)->setHidden(newBool);
          }
      
          this->endLoading();
      }
      

      And here is how I start the it

      QtConcurrent::run(this, &MainWidget::toggle);
      

      The first time I start this, it's OK. All the "hidden" items are shown, and vice-versa. The second time, it crashes during the execution of the QtConcurrent, and the debugger points to the asm instructions (I don't know ASM). I've also tried to put a qDebug() with a counter to see at which point it fails, if it's at the same item or not. It crashes randomly. Sometimes at the 35'000 th iteration, sometimes at 16'000th (rounded).

      I can't see how it could be related to thread safety as I disable the main GUI while the QtConcurrent is running (endLoading() is made to reenable to GUI). What am I missing?

      Thanks for your help.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by
      #2

      @Max13

      So based on that, when I click a button, a slot is executed (using QtConcurrent) to toggle the hidden attribute of all the QListWidgetItems contained in the QList<QListWidgetItem*>.

      This isn't allowed, so results are undefined (and undocumented).

      I can't see how it could be related to thread safety as I disable the main GUI while the QtConcurrent is running (endLoading() is made to reenable to GUI). What am I missing?

      You're missing the fact that QWidget and its descendants aren't reentrant.

      Kind regards.

      Read and abide by the Qt Code of Conduct

      M 2 Replies Last reply
      1
      • kshegunovK kshegunov

        @Max13

        So based on that, when I click a button, a slot is executed (using QtConcurrent) to toggle the hidden attribute of all the QListWidgetItems contained in the QList<QListWidgetItem*>.

        This isn't allowed, so results are undefined (and undocumented).

        I can't see how it could be related to thread safety as I disable the main GUI while the QtConcurrent is running (endLoading() is made to reenable to GUI). What am I missing?

        You're missing the fact that QWidget and its descendants aren't reentrant.

        Kind regards.

        M Offline
        M Offline
        Max13
        wrote on last edited by
        #3

        @kshegunov Thanks for the hint. That's also why using a QMutex didn't change anything. So, please tell me how can I perform the heavy tasks in background on the list? Do I need to set the QList in another class and/or maybe the QListWidget model?

        We all have started by asking questions. Then after some time, we can begin answering them.

        kshegunovK 1 Reply Last reply
        0
        • M Max13

          @kshegunov Thanks for the hint. That's also why using a QMutex didn't change anything. So, please tell me how can I perform the heavy tasks in background on the list? Do I need to set the QList in another class and/or maybe the QListWidget model?

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by kshegunov
          #4

          @Max13
          Do whatever is you want to do with GUI in the main thread and call QCoreApplication::processEvents manually so you don't freeze up the user interface. Something like this:

          void MainWidget::toggle()
          {
              bool newBool = !m_okItems.at(1)->isHidden(); //< Just use C++, all the pointer dereferencing is making my head spin
          
              typedef QList<QListWidgetItem *>::ConstIterator ListIterator;
              for (ListIterator i = m_okItems.constBegin(); i != m_okItems.constEnd(); ++i)  {
                  (*i)->setHidden(newBool);
                  QCoreApplication::processEvents();
              }
          
              endLoading();
          }
          

          Read and abide by the Qt Code of Conduct

          M 1 Reply Last reply
          0
          • kshegunovK kshegunov

            @Max13
            Do whatever is you want to do with GUI in the main thread and call QCoreApplication::processEvents manually so you don't freeze up the user interface. Something like this:

            void MainWidget::toggle()
            {
                bool newBool = !m_okItems.at(1)->isHidden(); //< Just use C++, all the pointer dereferencing is making my head spin
            
                typedef QList<QListWidgetItem *>::ConstIterator ListIterator;
                for (ListIterator i = m_okItems.constBegin(); i != m_okItems.constEnd(); ++i)  {
                    (*i)->setHidden(newBool);
                    QCoreApplication::processEvents();
                }
            
                endLoading();
            }
            
            M Offline
            M Offline
            Max13
            wrote on last edited by
            #5

            @kshegunov Too bad :( I was afraid that was the only possible way... I tried that but it slowed down my app (maybe because each time I'm refreshing the whole widget for 1 add).

            I think I can get around the visual issue by creating a "Loading" widget with a progress bar and all that things in a thread instead. Then, I won't have to care much about the main GUI freezing, isn't it?

            We all have started by asking questions. Then after some time, we can begin answering them.

            1 Reply Last reply
            0
            • kshegunovK kshegunov

              @Max13

              So based on that, when I click a button, a slot is executed (using QtConcurrent) to toggle the hidden attribute of all the QListWidgetItems contained in the QList<QListWidgetItem*>.

              This isn't allowed, so results are undefined (and undocumented).

              I can't see how it could be related to thread safety as I disable the main GUI while the QtConcurrent is running (endLoading() is made to reenable to GUI). What am I missing?

              You're missing the fact that QWidget and its descendants aren't reentrant.

              Kind regards.

              M Offline
              M Offline
              Max13
              wrote on last edited by
              #6

              @kshegunov said:

              You're missing the fact that QWidget and its descendants aren't reentrant.

              Actually, I missed more than that... I completely miss the fact that, when dealing with QWidget or simillar + threads, that exactely when I should have used signal/slot mechanism... I feel dumb about it, but anyway, the Crawler object now crawls using Qt::Concurrent and send a signal with the text to add to the QListWidget, and then a MainWidget's slot is called to create and add the item.

              Thanks for your help

              We all have started by asking questions. Then after some time, we can begin answering them.

              1 Reply Last reply
              1

              • Login

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