【问题标题】:Q_INVOKABLE does not expose method to QMLQ_INVOKABLE 不向 QML 公开方法
【发布时间】:2019-08-03 06:24:55
【问题描述】:

我想从 QML 调用 C++ 方法,并将参数传递给它。据我了解,我应该用宏Q_OBJECT 标记类,并用Q_INVOKABLE 标记所需的公共功能。

虽然我做到了,但我仍然遇到运行时错误

qrc:/main.qml:42: TypeError: Property 'addFile' of object QObject(0xf20e90) is not a function

这是我的.hpp.cpp 类文件:

lib_controller.hpp

#include <QObject>
#include <QString>
...

class LibController : public QObject{
    Q_OBJECT
    Q_PROPERTY(decltype(getProgress) progress READ getProgress NOTIFY ProgressChanged)
    public:
        ...

        Q_INVOKABLE
        void addFile(QString from_name, QString to_name);
        ...
};

lib_controller.cpp

#include "lib_controller.hpp"
...
void LibController::addFile(QString from_name, QString to_name){
    file_manager = new FileManager(from_name.toUtf8().constData(),
                                   to_name.toUtf8().constData());
}

...

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>

#include "lib_controller.hpp"

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

    // Registration of custom type
    qmlRegisterType<LibController>("com.sort.controller", 0, 1, "LibController");

    ...

    return app.exec();
}

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2
import com.sort.controller 0.1

...

     FileDialog {
        id: fileDialog_for_load
        title: "Load file"
        onAccepted: {
           fileDialog_for_save.open()
        }
    }
    FileDialog {
        id: fileDialog_for_save
        title: "Save file"
        onAccepted: {
            var loadPath = fileDialog_for_load.fileUrl.toString();
            loadPath = loadPath.replace(/^(file:\/{2})/,"");

            var savePath = fileDialog_for_save.fileUrl.toString();
            savePath = savePath.replace(/^(file:\/{2})/,"");

            console.log("Save Path:" + savePath)
            libController.addFile(loadPath, savePath)
        }
    }

LibController { id: libController }

我想要的是调用函数addFile() 来构造file_manager 成员然后它需要对新文件进行排序。

为什么会发生这个错误?我做错了什么?

【问题讨论】:

    标签: c++ qt qml qt5


    【解决方案1】:

    根据docsfileUrl属性,FileDialog返回一个url类型,它相当于C++类型QUrl而不是QString。所以你可以:

    • 编辑您的 C++ 方法以获取两个 QUrls。

    • 或者在你的 QML pass .fileUrl.toString().

    【讨论】:

    • 感谢您的回答!我将 QML 代码更改为 this,但错误仍然存​​在。也许它返回 JS 字符串,而不是 QString?还是其他地方有问题?
    • @nonForgivingJesus 请最小化代码并将问题隔离在MCVE
    • @nonForgivingJesus 我测试了你的代码,它运行良好。
    • 好吧,我的项目现在不知何故坏了,我会接受答案然后弄清楚如何让它再次工作......
    【解决方案2】:

    在你的 libcontroller 构造函数中,你删除你的私有成员而不是初始化它。

    【讨论】:

    • 天哪,感谢您发现此错误!但它并没有解决addFile 的问题,问题仍然存在......我稍微编辑了问题的结尾以使我的意图更清晰。
    【解决方案3】:

    我认为您在 main.qml 中缺少实例化 LibController { id:libController } 的组件。

    【讨论】:

    • 对不起,我没有提到这个,因为我认为它是多余的,但我有这个元素。我也编辑了问题
    猜你喜欢
    • 2012-07-17
    • 2021-03-16
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多