2014-12-13 102 views
6

我正在閱讀過去幾小時的Qt文檔,試圖找出一種方法來使用Qt Quick UI(QML)創建的UI與C++代碼(函數等)進行通信(交互)。集成C++和QML。 Qt 5.4

我已經閱讀了這裏的5或6個類似的問題,但我有點困惑,我有問題找出從哪裏開始或首先做什麼。 如果有人能花時間列出完成這項工作所需的步驟,我會非常感激。

我到目前爲止所做的工作。我試着做...>添加新項目> C++類,但我失敗了,說錯誤:「未能添加一個或多個文件到項目」>它似乎創建了文件(..。cpp和.h)他們在其他項目文件所在的文件夾中,但未包含在項目中。 我想要做的只是簡單的像通過C++函數或任何其他可能的方式更改文本文本的內容。

//Test.qml(main.qml)

import QtQuick 2.1 
    import QtQuick.Window 2.0 

Rectangle { 
    id: rootRect 
    width: Screen.width/2 
    height: Screen.height/2 
    color: "gray" 


    Button{} 

    Rectangle{ 
     id: textField 
     width: 120 
     height: 40 
     color: "white" 
     x:274; y: 61 
     border.color: "blue" 
     border.width: 4 
     radius: 2 

    } 

    TextEdit { 

     id: display 
     x: 274 
     y: 61 
     width: 80 
     height: 20 
     text: qsTr("Text Edit") 
     font.pixelSize: 22 
     color: "black" 
     anchors.centerIn: textField 

    } 

    Rectangle{ 
     id: inputField 
     width: textField.width 
     height: textField.height 
     border.color: "green" 
     border.width: 3 
     color: "white" 
     x: 140; y: 61 
    } 

    TextEdit{ 
     id: input 
     color: "red" 
     font.pixelSize: 30 
     anchors.centerIn: inputField 
     text: "Some Text" 


    } 

} 

//Button.cpl

import QtQuick 2.0 
import QtQuick.Window 2.0 


Item { 

    property string defaultText: "New Text" 


    Rectangle{ 
    id: button 
    width: rootRect.width/6 
    height: rootRect.height/8 
    color: "black" 
    x: 200; y: 200 
    radius: 10 

    } 

    MouseArea{ 
     id: buttonClickArea 
     width: 0 
     anchors.rightMargin: 0 
     anchors.bottomMargin: 0 
     anchors.fill: button 

     onClicked: { 

       display.text = defaultText 
     } 
    } 

} 

感謝您在百忙之中閱讀本和/或任何回覆的時間。

+2

我沒有看到任何試圖寫C++的一部分。至於你的錯誤 - 它看起來像你試圖添加C++類文件到'Qt Quick UI'項目。這種類型的項目只包含QML部分,並與qmlscene實用程序一起運行。你需要的是'Qt Quick Application'。項目創建後,您將準備好使用QML和C++文件的項目。所以現在你可以將C++類添加到項目中。請參閱[文檔](http://doc.qt.io/qt-5/qtqml-cppintegration-topic.html),瞭解如何將C++插件插入QML – folibis 2014-12-14 06:35:24

+2

順便說一句,QtQuick中已經有'Button'項目.Controls 1.3' – folibis 2014-12-14 06:37:53

+1

幾乎就是@folibis所說的:'New File or Project ...> Qt Quick Application'。你有QML和C++類。您在其他答案中找到的代碼可以在該來源中複製。 – BaCaRoZzo 2014-12-14 10:54:52

回答

13

使用Qt 5.4.0和Qt Creator 3.3.0,創建新項目:

  1. 單擊新建項目
  2. Qt Quick的應用
  3. 單擊選擇...
  4. 名稱項目和選擇放置的位置
  5. 單擊下一步
  6. 從下拉菜單中選擇Qt Quick 2.4
  7. 單擊下一步
  8. 選擇所需的工具包(S)
  9. 單擊下一步
  10. 單擊Finish

現在你應該可以看到下面的代碼開放main.qml文件:

import QtQuick 2.4 
import QtQuick.Window 2.2 

Window { 
    visible: true 
    MainForm { 
     anchors.fill: parent 
     mouseArea.onClicked: { 
      Qt.quit(); 
     } 

    } 
} 

將其更改爲:

import QtQuick 2.4 
import QtQuick.Window 2.2 

//### New Code ### 

import QtQuick.Controls 1.3 

//################ 

Window { 
    id: window1 
    visible: true 

    //### New Code ### 

    width: 400 
    height: 500 

    TextArea { 
     id: textArea 
     readOnly: true 
     anchors.bottom: textInput.top 
     anchors.bottomMargin: 6 
     anchors.right: parent.right 
     anchors.rightMargin: 8 
     anchors.left: parent.left 
     anchors.leftMargin: 7 
     anchors.top: parent.top 
     anchors.topMargin: 7 
    } 

    TextField { 
     id: textInput 
     y: 470 
     height: 23 
     anchors.right: sendButton.left 
     anchors.rightMargin: 6 
     anchors.bottom: parent.bottom 
     anchors.bottomMargin: 7 
     anchors.left: parent.left 
     anchors.leftMargin: 7 
    } 

    Button { 
     id: sendButton 
     x: 328 
     y: 470 
     width: 64 
     height: 23 
     text: qsTr("Send") 
     anchors.bottom: parent.bottom 
     anchors.bottomMargin: 7 
     anchors.right: parent.right 
     anchors.rightMargin: 8 

     onClicked: { 
      CppClass.sendMessage(textInput.text, textArea); 
      textInput.text = ""; 
     } 
    } 

    //################ 
} 

加入C++類到您的項目:

  1. 在項目查看器單擊鼠標右鍵項目名稱
  2. 單擊添加新...
  3. 選擇C++類,如果尚未選定
  4. 點擊選擇...
  5. 在類名申請進入 「CppClass」
  6. 組基類的QObject
  7. 單擊下一步
  8. 單擊Finish

打開cppclass.h並將其更改爲:

#ifndef CPPCLASS_H 
#define CPPCLASS_H 

#include <QObject> 

//### New Code ### 

#include <QQuickItem> 
#include <QQuickTextDocument> 
#include <QTextDocument> 

//################ 

class CppClass : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit CppClass(QObject *parent = 0); 
    ~CppClass(); 

    //### New Code ### 

    Q_INVOKABLE void sendMessage(const QString &msg, QQuickItem *textArea); 

    //################ 

signals: 

public slots: 
}; 

#endif // CPPCLASS_H 

打開cppclass.cpp並將其更​​改爲:

#include "cppclass.h" 

CppClass::CppClass(QObject *parent) : QObject(parent) 
{ 

} 

CppClass::~CppClass() 
{ 

} 
//### New Code ### 

void CppClass::sendMessage(const QString &msg, QQuickItem *textArea) 
{ 
    QTextDocument *textDocument = textArea->property("textDocument").value<QQuickTextDocument*>()->textDocument(); 

    textDocument->setHtml(textDocument->toHtml() + "\n<b>Text sent to Cpp side:</b> <i>" + msg + "</i>"); 
} 

//################ 

打開main.cpp中,更改爲:

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 

//### New Code ### 

#include <QQmlContext> 

#include "cppclass.h" 

//################ 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    QQmlApplicationEngine engine; 

    //### New Code ### 

    CppClass cppClass; 

    engine.rootContext()->setContextProperty("CppClass", &cppClass); 

    //################ 

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

    return app.exec(); 
} 

運行應用程序,鍵入一些文字輸入字段然後點擊發送。



針對動態Remo的評論這裏的另一種方式擁有QML和C++溝通。這種方法基於C++發出一個信號,QML作用於它。以下是讓它工作的代碼。


cppclass.h

#ifndef CPPCLASS_H 
#define CPPCLASS_H 

#include <QObject> 

#include <QDateTime> 

class CppClass : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit CppClass(QObject *parent = 0); 
    ~CppClass(); 

    Q_INVOKABLE void getCurrentTime(); 

signals: 
    void timeUpdate(QString currentTime); 

public slots: 
}; 

#endif // CPPCLASS_H 

cppclass.cpp

#include "cppclass.h" 

CppClass::CppClass(QObject *parent) : QObject(parent) 
{ 

} 

CppClass::~CppClass() 
{ 

} 

void CppClass::getCurrentTime() 
{ 
    emit timeUpdate(QDateTime::currentDateTime().toString("ddd dd MMMM yyyy hh:mm:ss.zzz")); 
} 

的main.cpp

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 

#include <QQmlContext> 

#include "cppclass.h" 

int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    CppClass cppClass; 

    QQmlApplicationEngine engine; 

    engine.rootContext()->setContextProperty("CppClass", &cppClass); 

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

    return app.exec(); 
} 

main.qml:

import QtQuick 2.4 
import QtQuick.Window 2.2 
import QtQuick.Controls 1.2 

Window { 
    id: rootWindow 
    width: 400 
    height: 400 
    visible: true 

    Connections { 
     target: CppClass 

     onTimeUpdate: { 
      initailizeDllMsg.text = currentTime 
     } 
    } 

    Text { 
     id: initailizeDllMsg 
     text: qsTr("{current time placeholder}") 
     font.pointSize: 14 
     anchors.horizontalCenter: parent.horizontalCenter 
     anchors.verticalCenter: parent.verticalCenter 
    } 

    Button { 
     id: button1 
     x: 163 
     y: 357 
     text: qsTr("Show current time") 
     anchors.bottom: parent.bottom 
     anchors.bottomMargin: 20 
     anchors.horizontalCenter: parent.horizontalCenter 

     onClicked: CppClass.getCurrentTime() 
    } 
} 
+0

這有助於很多:)我可以理解此訪問的TextArea和設置文本從TextField 。你還可以指導我如何改變QML文本的文本? 感謝你! 文本{ ID:initailizeDllMsg 文本:initailize_lbl } – 2016-04-06 14:19:18

+0

@DynamicRemo我已經更新我的答案來說明如何實現你想要的。 – 2016-04-07 12:20:52

+0

非常感謝。你救了我的一天 – HosSeinM 2016-11-10 20:29:04