2015-05-04 65 views
0

我正在嘗試編寫一個QtQuick程序,它用作用戶和幾個CLI應用程序之間的智能接口。我已經實現了QtQuick + JavaScript應用程序。C++信號和訪問QtQuick項目

QtQuick butten發出由C++層監聽的信號。到目前爲止,一切正常。

但是,在我的C++ 插槽函數中,我需要在QtQuick應用程序中寫入某個Item。此項目是一個TextArea,用作CLI應用程序的日誌輸出。這些CLI應用程序從C++中的插槽函數運行。我將它們的輸出存儲到一個變量中,並且我想在此日誌輸出TextArea中顯示此變量的輸出。

我嘗試了很多東西,但我沒有發現這樣做

回答

2

我倒是有類似的問題的正確方法。 這就是我解決它的方法。

在C++中我創建處理該命令與QProcess中(我暴露類QML),其readyToRead信號附加到C++函數在我的暴露類的類,該功能發出另一個信號showOutput與輸出文字。

有了這個信息,我只是我的新的信號連接到一個JavaScript函數在QML:

cppExposed.showOutput.connect(jsFunction); 

而在javascript函數我只是追加文本

function jsFunction(output) { 
    OutputTextArea.text += output; 
} 

爲了揭露C++屬性QML你可以看看這裏的文檔:http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html

我認爲最簡單的方法是創建一個cpp類的對象,並且s等在你的main.cpp上下文屬性之前加載main.qml: 事情是這樣的:

QQmlApplicationEngine engine; 
ProcessHandler procHandler; 
engine.rootContext()->setContextProperty("procHandler", &procHandler); 

現在,您可以訪問你的對象從QML直接的,並且可以連接信號

procHandler.showOutput.connect(jsFunction) 

而在你的C++類不要忘了與過程ReadyToReady信號連接,並與數據發出自己的信號:

void readyToRead() { 
    emit showOutput(m_proc.readAllStandardOutput()); 
} 

UPDATE: 你的財產前應設置由發動機加載QML文件:

AnalyzeSignal analyzeSignal; 
engine.rootContext()->setContextProperty("analyzeSignal", &analyzeSignal); 
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

而且我不認爲你需要writeToLogOutput是一個屬性(它有一些語法錯誤的BTW),這是一個信號方法,對吧?所以它可以作爲信號自動提供給QML,而不是屬性。

請勿創建新的QQMLContext。 在這行你正在做的是創造一個新的QQMLContext

QQmlContext *context = new QQmlContext(engine.rootContext()); 
context->setContextProperty("analyzeSignal", &analyzeSignal); 

這是行不通的,因爲你的屬性設置爲新創建的上下文,而不是原來的根上下文。

+0

我明白了,但我不知道如何「將類暴露給QML」。我在github上有我的測試項目:https://github.com/lejmr/qtquicktest。我創建了插槽功能的信號,但我不知道如何將QML函數連接到此信號。謝謝您的幫助! –

+0

我會通過更多信息更新答案。 – danielfranca

+0

謝謝你的參考!我幾乎在那裏,但我仍然得到這個錯誤:qrc:/main.qml:74:ReferenceError:analyzeSignal未定義..源代碼在github上更新 –

0

我的主要功能的最終解決方案是這樣的:

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    QQmlApplicationEngine engine; 

    AnalyzeSignal analyzeSignal; 
    QQmlContext *context = engine.rootContext(); 
    context->setContextProperty("analyzeSignal", &analyzeSignal); 

    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

    // Registering slot onto a signal 
    QObject *win = engine.rootObjects()[0]; 
    QObject *item = win->findChild<QObject*>("myButton"); 
    QObject::connect(item, SIGNAL(doAnalyzeSignal(QString,QString,QString,QString)), &analyzeSignal, SLOT(cppSlot(QString,QString,QString,QString))); 

    return app.exec(); 
} 

而這個作品!