Behavior of updating a C ++ model from another thread from which the QML engine QtQuick2 is running

The script has the following components:

  • C ++ QAbstractItemModel derived model class created on main thread
  • QML QtQuick2 Engine created on main thread
  • Worker boost :: thread spawned from main thread on user interaction

The relationship between these components:

  • The C ++ model is opened via the Q_PROPERTY type registered with qmlRegisterSingletonType <> () in the QML Engine.
  • The worker thread updates the model with a method that calls "emit data_changed (...)"

Question: in which thread does the "emit data_changed (...)" callback occur?

Note

The key element in this question is that the initial thread doesn't know qt.

+3


source to share


1 answer


I am assuming the worker thread is calling the signal method on some QObject

. This is completely thread safe and the right thing to do. The signal implementation compares the current stream with the stream of each slot and determines which connection to use (if the connection is automatic).

As long as you connect to the specified signal using auto or posed connections, the slots will be called in thread()

your instance QObject

.

It doesn't matter which thread the signal is called on, and it doesn't matter if that thread is a Qt thread or not.



If you provide a context object to a functor connection, the functor will execute on the context object's thread, so you can make thread-safe calls to the functor on the objects this way :)

For example:

#include <QtCore>
#include <thread>

class Object : public QObject {
  Q_OBJECT
public:
  Q_SIGNAL void ping();
  Q_SLOT void pong() { 
    qDebug() << "hello on thread" << QThread::currentThread();
    qApp.quit();
  });
};

int main(int argc, char ** argv) {
  QCoreApplication app(argc, argv);
  Object obj;
  qDebug() << "main thread is" << QThread::currentThread();
  QObject::connect(&obj, &Object::ping, &obj, &Object:pong);
  QObject::connect(&obj, &Object::ping, []{
    qDebug() << "context-free functor invoked on thread" << QThread::currentThread();
  });
  QObject::connect(&obj, &QObject::ping, &obj, []{
    qDebug() << "context-ful functor invoked on thread" << QThread::currentThread();
  });
  auto thread = std::thread([&obj]{
    emit obj.ping();
  });
  int rc = app.exec();
  thread.join();
  return rc;
}
#include "main.moc"

      

+1


source







All Articles