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. Emit signal from QtConcurrent::run thread

Emit signal from QtConcurrent::run thread

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 3 Posters 776 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.
  • B Offline
    B Offline
    Bob64
    wrote on last edited by
    #1

    A question I read on here and some subsequent Googling has left me unsure as to whether something I was intending to do will be correct.

    I am using a class Wrapped from an "external" non-Qt library and calling a do_task method on it. This blocks and can take some time so I would like to run it in a thread and emit a signal when it is complete. It implements its own notification method based on vanilla C++ callback registration. The basic idea is to wrap it into a QObject-based class which exposes a non-blocking do_task and will emit a signal on completion.

    My intention was to do something like this:

    void Wrapper::setup() {
      // m_wrapped is a 'Wrapped' instance - a non-Qt object
      m_wrapped->registerOnConnected([&]() {
        // This is a callback from Wrapped::do_task which in practice
        // is executed in the thread of QtConcurrent::run below
        emit taskComplete(); // signal of current 'Wrapper' class
      });
    }
    
    void Wrapper::do_task(task_info info) {
      QtConcurrent::run([&]() { m_wrapped->do_task(info); });
    }
    ...
    
    void Client::setup() {
      connect(m_wrapper, &Wrapper::taskComplete,
              this, &Client::onTaskComplete);
    }
    

    Should this be OK?

    My understanding was that Qt is quite good at dealing with the passing of signals across threads and that the default behaviour of the connect(...) above should be sufficient. My concern now is that this will not work in the context of QtConcurrent::run and that I should use a different Qt threading facility. (I thought of using QtConcurrent::run as it seemed like the most minimal approach available.)

    Axel SpoerlA 1 Reply Last reply
    0
    • B Bob64

      A question I read on here and some subsequent Googling has left me unsure as to whether something I was intending to do will be correct.

      I am using a class Wrapped from an "external" non-Qt library and calling a do_task method on it. This blocks and can take some time so I would like to run it in a thread and emit a signal when it is complete. It implements its own notification method based on vanilla C++ callback registration. The basic idea is to wrap it into a QObject-based class which exposes a non-blocking do_task and will emit a signal on completion.

      My intention was to do something like this:

      void Wrapper::setup() {
        // m_wrapped is a 'Wrapped' instance - a non-Qt object
        m_wrapped->registerOnConnected([&]() {
          // This is a callback from Wrapped::do_task which in practice
          // is executed in the thread of QtConcurrent::run below
          emit taskComplete(); // signal of current 'Wrapper' class
        });
      }
      
      void Wrapper::do_task(task_info info) {
        QtConcurrent::run([&]() { m_wrapped->do_task(info); });
      }
      ...
      
      void Client::setup() {
        connect(m_wrapper, &Wrapper::taskComplete,
                this, &Client::onTaskComplete);
      }
      

      Should this be OK?

      My understanding was that Qt is quite good at dealing with the passing of signals across threads and that the default behaviour of the connect(...) above should be sufficient. My concern now is that this will not work in the context of QtConcurrent::run and that I should use a different Qt threading facility. (I thought of using QtConcurrent::run as it seemed like the most minimal approach available.)

      Axel SpoerlA Offline
      Axel SpoerlA Offline
      Axel Spoerl
      Moderators
      wrote on last edited by
      #2

      @Bob64
      The example code looks fine and you may expect cross-thread signal delivery to work smoothly.
      The architecture has to be thread-safe, but you sound pretty much like you know what you do.

      Software Engineer
      The Qt Company, Oslo

      1 Reply Last reply
      3
      • B Bob64 has marked this topic as solved on
      • S Offline
        S Offline
        SimonSchroeder
        wrote on last edited by
        #3

        I would expect that do_task will return after it is done. QtConcurrent::run will return a QFuture. In order to get a signal out of that you can use a QFutureWatcher. Since your callback does not seem to provide any additional parameters I would personally prefer this approach.

        (If there are additional callback, e.g. for progress, a wrapper class makes more sense.)

        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