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. Running QtConcurrent on member function resulting in error
Forum Updated to NodeBB v4.3 + New Features

Running QtConcurrent on member function resulting in error

Scheduled Pinned Locked Moved Solved General and Desktop
qtconcurrent
8 Posts 2 Posters 791 Views 2 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.
  • W Offline
    W Offline
    wcneill
    wrote on 17 Nov 2022, 19:24 last edited by wcneill
    #1

    Re: Creating a new thread with QtConcurrent did not work

    I'll caveat this question with this: I am new to C++ (interpret pointers boggle my mind)

    I am following the documentation for QtConcurrent::run here: https://doc.qt.io/qt-6/qtconcurrentrun.html#additional-api-features

    I am attempting to run the following code:

        // This is a pointer to an Engine object from third party library LUI. 
        auto engine = lui::QueryInterop<wise::Engine>(lui::GetLUI());
        if (engine) {
    
            connect(&m_modelsLoadedWatcher, &QFutureWatcher<bool>::finished, this, &ConfigDialog::onNNModelsLoaded);
    
            // Begin loading models in new thread. 
            m_modelsLoadedFuture = QtConcurrent::run(&wise::Engine::loadPytorchModelsAsync, engine);
            m_modelsLoadedWatcher.setFuture(m_modelsLoadedFuture);
    
     
        } else {
           // do some stuff.
        }
    

    However, I am consistently getting the following error.
    ec23d1b9-1a70-4618-81b9-d0042c217d5c-image.png

    I figure something in the called member function must not be compatible. This is what it looks like:

    void Engine::loadPytorchModelsAsync() { 
        QString scriptModulesPath = QDir("plugins:").absolutePath() + QString("/wisePlugin/PyTorchModels/");
    
        // spread out the processing of our heavy NN model loads over multiple threads
        auto pytorchLoadFunctions = wise::nn::GetPyTorchModelLoaders(scriptModulesPath);
        auto numberOfModelsToLoad = pytorchLoadFunctions.size();
        auto progress = new QProgressDialog("Loading Neural Network Models...", "", 0, (int)pytorchLoadFunctions.size(),
                                            lui::GetLUI()->getUI()->mainWindow()->centralWidget());
    
        progress->setCancelButton(nullptr);
        progress->setMinimumDuration(0);
        progress->setValue(0);
    
        // Define lambda function which will update progress bar when a model is loaded.
        wise::IEngine::SubTaskCompleteFunction actionOnComplete = [progress, numberOfModelsToLoad](int numComplete) {
            // invoke on the main thread
            QMetaObject::invokeMethod(qApp, [progress, numComplete] {
                progress->raise(); // bring the widget to the front of the app
                progress->setValue(numComplete);
            });
        };
    
        // Queue load functions
        QueueSimpleBlockingTaskGroup(pytorchLoadFunctions, wise::IEngine::eTaskBlockType::BlockAWorkerThread, actionOnComplete);
    }
    

    I'm not sure where to go from here honestly. It seems that I am following the documentation perfectly but I know that can't be true or this would be working. Can someone show me what I need to correct?

    1 Reply Last reply
    0
    • S SGaist
      17 Nov 2022, 20:51

      The correct way is to not do GUI access in a method called through QtConcurrent::run.

      Emit a signal or use invokeMethod but no direct access.

      W Offline
      W Offline
      wcneill
      wrote on 17 Nov 2022, 23:30 last edited by wcneill
      #8

      @SGaist

      I got it to work by making the QFuture member variable of the class that was handling the GUI stuff, then just accessing it from the class I was working on above.

      if (engine) {
      
              // Engine has a QFuture<void> member for the models being loaded. We will watch it here. 
              connect(&m_modelsLoadedWatcher, &QFutureWatcher<bool>::finished, this, &ConfigDialog::onNNModelsLoaded);
      
              // We know that the implementation of IEngine is Engine, so cast. 
              m_modelsLoadedWatcher.setFuture(dynamic_cast<wise::Engine*>(engine)->m_modelsLoadedFuture);
      
          }
      

      Im curious however about the invokeMethod you were talking about. I started a new thread asking about it, as I did try it out: https://forum.qt.io/topic/140834/how-to-combine-qtconcurrent-with-qmetaobject-invokemethod.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 17 Nov 2022, 19:48 last edited by
        #2

        Hi and welcome to devnet,

        To rule out the obvious, can you build the example successfully ?

        On a side note: you code snippet does not match the error you show in the image.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        W 1 Reply Last reply 17 Nov 2022, 20:29
        1
        • W Offline
          W Offline
          wcneill
          wrote on 17 Nov 2022, 20:06 last edited by
          #3
          This post is deleted!
          1 Reply Last reply
          0
          • S SGaist
            17 Nov 2022, 19:48

            Hi and welcome to devnet,

            To rule out the obvious, can you build the example successfully ?

            On a side note: you code snippet does not match the error you show in the image.

            W Offline
            W Offline
            wcneill
            wrote on 17 Nov 2022, 20:29 last edited by wcneill
            #4

            @SGaist As it turns out, I was looking at the docs for the wrong version. The arguments just needed to be flipped. Thanks for pointing out the difference.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 17 Nov 2022, 20:31 last edited by
              #5

              Now that you mention it, I remember that I thought that there would some trouble with that. Nice catch !

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • W Offline
                W Offline
                wcneill
                wrote on 17 Nov 2022, 20:47 last edited by wcneill
                #6

                @SGaist said in Running QtConcurrent on member function resulting in error:

                Now that you mention it, I remember that I thought that there would some trouble with that. Nice catch !

                Hah, a co-worker taught me how to use intellisense to filter out the 96 overrides of QtConcurrent::run to discover the error :D

                I'm running into new problems now (widgets must be created in GUI thread)... I found this thread which you participated in here, and take its contents to imply that I am calling QtConcurrent::run from a thread that is not the GUI thread, so any widgets created by that call will make this error occur.

                Unfortunately, I'm not sure which thread is the GUI thread, so I guess I just have to move the run call around into different cpp files until I find the right one?

                I feel out of my depth here. I normally write models in Python and someone else does all this C++ work for me. This is what I get for volunteering to learn something new :D

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 17 Nov 2022, 20:51 last edited by
                  #7

                  The correct way is to not do GUI access in a method called through QtConcurrent::run.

                  Emit a signal or use invokeMethod but no direct access.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  W 1 Reply Last reply 17 Nov 2022, 23:30
                  1
                  • S SGaist
                    17 Nov 2022, 20:51

                    The correct way is to not do GUI access in a method called through QtConcurrent::run.

                    Emit a signal or use invokeMethod but no direct access.

                    W Offline
                    W Offline
                    wcneill
                    wrote on 17 Nov 2022, 23:30 last edited by wcneill
                    #8

                    @SGaist

                    I got it to work by making the QFuture member variable of the class that was handling the GUI stuff, then just accessing it from the class I was working on above.

                    if (engine) {
                    
                            // Engine has a QFuture<void> member for the models being loaded. We will watch it here. 
                            connect(&m_modelsLoadedWatcher, &QFutureWatcher<bool>::finished, this, &ConfigDialog::onNNModelsLoaded);
                    
                            // We know that the implementation of IEngine is Engine, so cast. 
                            m_modelsLoadedWatcher.setFuture(dynamic_cast<wise::Engine*>(engine)->m_modelsLoadedFuture);
                    
                        }
                    

                    Im curious however about the invokeMethod you were talking about. I started a new thread asking about it, as I did try it out: https://forum.qt.io/topic/140834/how-to-combine-qtconcurrent-with-qmetaobject-invokemethod.

                    1 Reply Last reply
                    0

                    8/8

                    17 Nov 2022, 23:30

                    • Login

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