Emit signal from QtConcurrent::run thread
-
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 ado_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-blockingdo_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 ofQtConcurrent::run
and that I should use a different Qt threading facility. (I thought of usingQtConcurrent::run
as it seemed like the most minimal approach available.) -
@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. -
-
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.)