【问题标题】:Calling C++ method from QML (Qt Quick application)从 QML(Qt Quick 应用程序)调用 C++ 方法
【发布时间】:2012-12-11 07:48:45
【问题描述】:

所以,我进行了一些搜索,但我读过的类似问题都没有有效的建议。

我正在使用 Qt Creator(而且我对 Qt 不太熟悉)所以我不确定它在后台做了什么伏都教。但是,我使用的是标准 Qt Quick Application 项目。

本质上,我想从 QML 调用一个 C++ 函数,该函数返回一个字符串,定期替换布局中的某些文本。

这里是 main.cpp:

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


class testClass : public QObject
{
    Q_OBJECT
public:
    Q_INVOKABLE QString gimmeText() {
            return QString("new text");
}
};



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/Picenter2/main.qml"));

    testClass t;
    viewer.rootContext()->setContextProperty("testOb", &t);

    viewer.showFullScreen();

    return app->exec();
}

这是布局的一个 sn-p(因为其中大部分显然是无关紧要的):

Text {
    id: text1
    x: 105
    y: 156
    color: "#ffffff"
    text: qsTr("text")
    font.pixelSize: 12
    Timer {
        interval: 1000; running: true; repeat: false
        onTriggered: text1.text = testOb.gimmeText();
    }

给出的错误是:

invalid use of incomplete type 'struct QDeclarativeContext' main.cpp (28)
forward declaration of 'struct QDeclarativeContext' qdeclarativeview.h (60)

编辑:包含 QDeclarativeContext 后,上述内容消失,出现以下错误:

(.text.startup+0x3e):-1: error: undefined reference to `vtable for testClass'
(.text.startup+0xcf):-1: error: undefined reference to `vtable for testClass'
(.text.startup+0x12b):-1: error: undefined reference to `vtable for testClass'
:-1: error: collect2: ld returned 1 exit status

我没有做过很多 C++ 编程,所以我并不完全熟悉这意味着什么。遵循基本相同问题的建议只会给我 vtable 错误或更难以理解的东西。

真正让我困惑的是,查看头文件,QmlApplicationViewer 是从 QDeclarativeView 派生的,这正是 Qt 文档使用 here 来完成我想要的工作。感谢任何人的任何建议。

【问题讨论】:

  • 错误消息意味着编译器知道有一个名为“QDeclarativeContext”的类,但不知道解析函数调用所需的细节(例如)。查找声明该类的标头并将该标头包含在您的示例中。
  • 这就是我读到的。所以,我把它包括在内。它只给了我三个“未定义的对 `vtable for testClass' 的引用”错误。
  • 好的,所以缺少的符号会从你自己的 testClass 中流出来。如果我猜对了,qt 附带了一个特殊工具,它可以从 Q_OBJECT 和 Q_INVOKABLE 宏创建代码。您应该将该类移动到单独的标题中。听起来很蹩脚,但试一试;-)
  • undefined reference to vtable 通常表示你需要重建项目(make clean + qmake + make)
  • 自从moc 使用元数据生成代码的应用程序仅由标头运行时,它就起作用了。在 *.pro 文件中添加 *.cpp 文件作为头文件会产生相同的效果(但这是一种讨厌的方法)。

标签: c++ qt qt-quick


【解决方案1】:

您必须注册您的课程才能在 QML 中使用它。您可以在主函数中执行此操作。您也必须在 QML 代码中导入它。您的代码应如下所示:

main.cpp:

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

#include <QtDeclarative>    // Required for registration


class testClass : public QObject
{
    Q_OBJECT
    public:
    Q_INVOKABLE QString gimmeText() {
            return QString("new text");
    }
};



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

    qmlRegisterType<testClass>("MyCustomQMLObjects", 2, 35, "testClassNameInQML");

    QmlApplicationViewer viewer;

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

    testClass t;
    viewer.rootContext()->setContextProperty("testOb", &t);

    viewer.showFullScreen();

    return app->exec();
}

QML 代码:

// ...

import MyCustomQMLObjects 2.35

// ...

property testClassNameInQML testOb

// ...

Text {
    id: text1
    x: 105
    y: 156
    color: "#ffffff"
    text: qsTr("text")
    font.pixelSize: 12
    Timer {
        interval: 1000; running: true; repeat: false
        onTriggered: text1.text = testOb.gimmeText();
    }

// ...

【讨论】:

    【解决方案2】:

    我没有使用qt 的经验,而且我看不到代码中的什么触发了错误。但是,当发生此类错误时,这是​​因为一个类 (struct QDeclarativeContext) 已前向声明,但使用时就像知道整个定义一样(访问成员,声明变量这种类型等)。要解决此问题,您需要包含具有此类型定义的标头

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2023-03-14
      • 1970-01-01
      • 2011-03-27
      • 2018-05-14
      • 1970-01-01
      相关资源
      最近更新 更多