2015-07-28 14 views
3

不同的線程的情況下具有以下組件:行爲一個C模型更新的++從其中QML QtQuick2發動機運行

    在主線程創建
  • C++化QAbstractItemModel派生模型類
  • QML QtQuick2引擎實例中主線程
  • 工人的boost ::線程從主線程在用戶互動催生

這些組件之間的關係:

  • C++模型通過qmlRegisterSingletonType(註冊爲qmlRegisterSingletonType)的類型的Q_PROPERTY公開給QML引擎。其中線程做的「發射data_changed(...)」發生回調:
  • 工作者線程通過調用方法「發出data_changed(......)」

問題更新模型?

注意

在這個問題上的一個關鍵因素是,啓動線程不是QT知道。

回答

1

我假設工作者線程在某些QObject上調用信號方法。這是完全線程安全的,也是一個有效的事情。信號的實現將當前線程與每個插槽的線程進行比較,並確定使用哪種連接(如果連接是自動類型的)。

只要您使用自動或排隊連接連接到所述信號,將在其QObject實例的thread()中調用這些插槽。

信號被調用的線程無關緊要,並且該線程是否爲Qt線程並不重要。

如果你提供了一個上下文對象的函子的連接,仿函數將在上下文對象的線程中執行,所以你可以在對象上做線程安全的仿函數調用這種方式:)

例如:

#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" 
+0

謝謝,這幫了很多!關鍵是把它煮成一個在主線程中創建的QObject,並從另一個線程發出信號。 我唯一不能100%(如毫無疑問)是cpp模型和QML引擎之間的信號和插槽的連接類型是自動類型或排隊類型。儘管如此,這似乎是一個合理的假設。 另外你的例子是非常有用的,但它並沒有爲我編譯。 [這裏](https://gist.github.com/psimona/ecefd220cf0d40e31b9d)是一個修訂版本。隨意編輯您的文章,以包括它,如果你想。 – ramses728

+0

@ ramses728在末尾添加'#include「main.moc」'行然後重新運行qmake並重新編譯。 –

+0

工作仍然有一些語法錯誤更新[git gist](https://gist.github.com/psimona/ecefd220cf0d40e31b9d) – ramses728