2012-02-29 46 views
21

Tôi đang cố gắng tạo một chương trình nhỏ với Qt. Tôi có một main.cpp với đoạn mã sau:Truy cập chức năng C++ từ QML

#include <QtGui/QApplication> 
#include "qmlapplicationviewer.h" 

Q_DECL_EXPORT int main(int argc, char *argv[]) 
{ 
    QScopedPointer<QApplication> app(createApplication(argc, argv)); 

    QmlApplicationViewer viewer; 
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); 
    viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml")); 
    viewer.showExpanded(); 

    return app->exec(); 
} 

int reken_tijden_uit(){ 
    return true; 
} 

và tôi có một tập tin .qml:

import QtQuick 1.1 

Rectangle { 

width: 360 
height: 360 
Text { 
    text: qsTr("Hello World") 
    anchors.centerIn: parent 
} 
MouseArea { 
    anchors.fill: parent 
    onClicked: { 
     Qt.quit(); 
    } 
} 
} 

Bây giờ, khi tôi bấm vào MouseArea, chương trình bỏ. Điều tôi muốn là nó gọi hàm reken_tijden_uit trong tệp main.cpp.

Tôi đã googled rất nhiều và tìm kiếm trên trang web này. Tôi đã tìm thấy một vài câu trả lời, nhưng tôi đã không nhận được một câu trả lời.

Vì vậy, tôi nên đặt mã nào để tôi có thể gọi hàm reken_tijden_uit bằng C++?

Xin cảm ơn trước.


File header trông như thế này:

#ifndef EIGEN_FUNCTION_HEADER_H 
#define EIGEN_FUNCTION_HEADER_H 

class MyObject : public QObject{ 
    Q_OBJECT 
public: 
    explicit MyObject (QObject* parent = 0) : QObject(parent) {} 
    Q_INVOKABLE int reken_tijden_uit(){ 
    return 1; 
    } 
}; 

#endif // EIGEN_FUNCTION_HEADER_H 

main.cpp:

#include <QtGui/QApplication> 
#include "qmlapplicationviewer.h" 
#include "eigen_function_header.h" 

QScopedPointer<QApplication> app(createApplication(argc, argv)); 

qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject"); 

Q_DECL_EXPORT int main(int argc, char *argv[]) 
{ 
    QScopedPointer<QApplication> app(createApplication(argc, argv)); 

    QmlApplicationViewer viewer; 
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); 
    viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml")); 
    viewer.showExpanded(); 

    return app->exec(); 
} 

và file QML:

import QtQuick 1.1 
import com.myself 1.0 

Rectangle { 
    width: 360 
    height: 360 
    Text { 
     text: qsTr("Hello World") 
     anchors.centerIn: parent 
    } 
    MyObject { 
     id: myobject 
    } 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      myobject.reken_tijden_uit() 
     } 
    } 
} 

Và các lỗi như sau:

D:\*\main.cpp:6: error: 'argc' was not declared in this scope 
D:\*\main.cpp:6: error: 'argv' was not declared in this scope 
D:\*\main.cpp:8: error: expected constructor, destructor, or type conversion before '<' token 

Vì vậy, tôi đã làm gì sai?

+0

hãy kiểm tra các chủ đề sau đây có thể giúp bạn http: // stackoverflow.com/questions/5709820/communication-between-c-and-qml – shofee

+0

hy, tôi đã kiểm tra nó, nhưng nó không phải là precisly những gì tôi muốn ... tôi muốn thêm một sự kiện onclick để mousearea các cuộc gọi chức năng cpp. (trong javascript là nó chỉ reken_tijden_uit(), vì vậy làm thế nào nó hoạt động trong c + + và qml ... – Mathlight

Trả lời

33

Đối với bất kỳ mã C++ nào được gọi từ QML, nó phải nằm trong một QObject.

Những gì bạn cần làm là tạo một lớp hạ thế với hàm của bạn, đăng ký nó vào QML, khởi tạo nó trong QML của bạn và gọi hàm đó. Cũng lưu ý rằng bạn phải đánh dấu chức năng của mình bằng Q_INVOKABLE.

Code:

#ifndef EIGEN_FUNCTION_HEADER_H 
#define EIGEN_FUNCTION_HEADER_H 

#include <QObject> 

class MyObject : public QObject{ 
    Q_OBJECT 
public: 
    explicit MyObject (QObject* parent = 0) : QObject(parent) {} 
    Q_INVOKABLE int reken_tijden_uit(){ 
    return 1; 
    } 
}; 

#endif // EIGEN_FUNCTION_HEADER_H 

main.cpp:

#include <QtGui/QApplication> 
#include <QtDeclarative> 

#include "qmlapplicationviewer.h" 
#include "eigen_function_header.h" 

Q_DECL_EXPORT int main(int argc, char *argv[]) 
{ 
    QScopedPointer<QApplication> app(createApplication(argc, argv)); 
    qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject"); 

    QmlApplicationViewer viewer; 
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); 
    viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml")); 
    viewer.showExpanded(); 

    return app->exec(); 
} 

QML:

import QtQuick 1.1 
import com.myself 1.0 

Rectangle { 

    width: 360 
    height: 360 
    Text { 
     text: qsTr("Hello World") 
     anchors.centerIn: parent 
    } 
    MyObject { 
     id: myobject 
    } 

    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      console.log(myobject.reken_tijden_uit()) 
     } 
    } 
} 
+0

và nơi nào tôi cần phải đặt đoạn mã đầu tiên? – Mathlight

+0

Tốt nhất, trong một riêng biệt .cpp/.h thêm cho dự án của bạn Đừng quên bao gồm .h trong main.cpp trước khi thực hiện qmlRegisterType – Koying

+0

được rồi, tôi đã gặp một vài lỗi, tôi sẽ đăng câu trả lời mới để rõ ràng là vấn đề là gì ... – Mathlight

0

Để thay thế cho qmlRegisterType() trong main.cpp, bạn cũng có thể sử dụng các thuộc tính ngữ cảnh để tạo QO các biến bject có sẵn trong QML. (Trong trường hợp bạn không yêu cầu tạo các thể hiện khác nhau của đối tượng của bạn với QML sau này).

Q_DECL_EXPORT int main(int argc, char *argv[]) 
{ 
    QScopedPointer<QApplication> app(createApplication(argc, argv)); 

    QmlApplicationViewer viewer; 
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); 
    viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml")); 
    viewer.showExpanded(); 

    // add single instance of your object to the QML context as a property 
    // the object will be available in QML with name "myObject" 
    MyObject* myObject = new MyObject(); 
    viewer.engine()->rootContext()->setContextProperty("myObject", myObject); 

    return app->exec(); 
} 

Trong QML, bạn có thể truy cập đối tượng từ bất kỳ nơi nào trong mã của bạn với tên được chỉ định trong main.cpp.Không kê khai bổ sung yêu cầu:

MouseArea { 
    anchors.fill: parent 
    onClicked: { 
     myObject.reken_tijden_uit() 
    } 
} 

Bạn có thể tìm thêm thông tin về QML < - khả năng> C++ truyền thông ở đây: https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml

Các vấn đề liên quan