I have built a small test example to better understand the QML/C++ bindings offered by Qt 5.
The QML side is basically a StackLayout with several Page that display informations on the console or in a Label. The user is able to navigate through these pages using a Button.
As long as everything runs in a single thread, it's fine.
The QML/C++ bindings through QObject's signals and slots are working as expected.
But when i try to move the QObject exposed to the QML in another thread, i get this message and the application is killed :
QQmlEngine: Illegal attempt to connect to BackendWorker(0xbe8a7c28) that is in a different thread than the QML engine QQmlApplicationEngine(0xbe8a7c44.
Here is the main of the application :
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    BackendWorker backendWorker; // expose a signal and a slot only
    QQmlApplicationEngine engine;
    QQmlContext *ctx = engine.rootContext();
    ctx->setContextProperty("backendWorker", &backendWorker);
    QThread t1;
    backendWorker.moveToThread(&t1); // here is the offending part
    t1.start();
    engine.load(QUrl(QStringLiteral("qrc:/UI/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}
Does all QObject's exposed to QML ( with properties, signals or slots or Q_INVOKABLE's) have to live in the same thread as the QGuiApplication ?
EDIT :
Here is a smaller example that shows a QStringListModel living in a separate thread than the QML ListView and it works, so how is this possible ?
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QStringListModel>
#include <QQmlContext>
#include <QTimer>
#include <QThread>
class Functor
{
public:
    Functor(QStringListModel *model) : m_model(model) { }
    void operator()() {
        QStringList list;
        list << "item 5" << "item 6" << "item 7" ;
        m_model->setStringList(list);
    }
private:
    QStringListModel *m_model;
};
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QStringListModel listModel;
    Functor functor(&listModel);
    QQmlApplicationEngine engine;
    QQmlContext *ctx = engine.rootContext();
    ctx->setContextProperty("listModel", &listModel);
    QThread t1;
    QStringList list;
    list << "item 1" << "item 2" << "item 3" << "item 4" ;
    listModel.setStringList(list);
    listModel.moveToThread(&t1);
    t1.start();
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    QTimer::singleShot(5000, functor);
    return app.exec();
}
QML side :
// main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
    visible: true
    ListView {
        width: 200
        height: 500
        anchors.centerIn: parent
        model: listModel
        delegate: Rectangle {
            height: 50
            width: 200
            Text {
                text : display
            }
        }
    }
}
Thank you.
 
    