美文网首页Qt & QML 日记
怎么将 C ++ 文件中的数据或对象暴露给 QML 使用?

怎么将 C ++ 文件中的数据或对象暴露给 QML 使用?

作者: ENG八戒 | 来源:发表于2019-01-08 20:54 被阅读9次

    以下内容为本人的学习笔记,如需要转载,请声明原文链接 [englyf] https://www.jianshu.com/p/55a9d76fc552

    请注意这里使用的是 Qt5.12 + vs2017x64

    开门见山,怎么在 QML 文件中引用 C ++ 文件里定义的内容?
    很简单,我们可以在 C ++ 文件中通过 QML 引擎(QQmlEngine class)的上下文对象(QQmlContext)调用方法 setContextProperty 设置对应的引用即可。详情看看下面的方法声明:

    void QQmlContext::setContextProperty(const QString &name, QObject *value);
    void QQmlContext::setContextProperty(const QString &name, const QVariant &value);

    可以看到,既可以设置 QObject 类型的对象(指针),也可以设置 QVariant 兼容的类型数据(包括基本类型数据等)到 QML 引擎的上下文中。然后在 QML 中就可以通过引用名 name 直接调用即可。

    1. 设置类型数据
    \\ main.cpp
    #include <QDateTime>
    void main() {
        \\...
        QQmlEngine engine;
        QDateTime dateTime = QDateTime::currentDateTime();
        engine.rootContext()->setContextProperty("dateTime", &dateTime);
        \\...
    }
    

    以上代码中直接将 QDateTime 类型的数据设置到引擎上下文中。

    Rectangle {
        id: window
        \\...
        Text {
          text: dateTime
        }
    }
    

    通过引用名 dateTime 将 C ++ 文件中的数据绑定到组件 Text 的 text 属性上,进而显示出来。

    2. 设置对象指针

    上面是设置数据,这里设置的是 QObject 类型的指针,所以,在 QML 里还可以调用 C ++ 文件中定义的对象,包括属性和方法等。

    先定义一个 QObject 的派生类 ApplicationData:

    //applicationdata.h
    #include <QObject>
    #include <QDateTime>
    #include <QTimer>
    
    class ApplicationData : public QObject
    {
        Q_OBJECT
    
    public:
        ApplicationData(){
            QTimer *timer = new QTimer(this);
            connect(timer, &QTimer::timeout, this, &ApplicationData::slt_timeout);
            timer->start(1000);
        }
    
        Q_INVOKABLE QDateTime getCurrentDateTime() const {
            return m_currentDateTime;
        }
    
    signals:
        void sig_dataTimeUpdated();
    
    private slots:
        void slt_timeout() {
            m_currentDateTime = QDateTime::currentDateTime();
            emit sig_dataTimeUpdated();
        }
    
    private:
        QDateTime m_currentDateTime;
    };
    

    其中 Q_INVOKABLE 用于声明此方法可被元对象系统调用。这个类实现每 1000 ms 刷新内部日期时间属性,并且发射信号 sig_dataTimeUpdated,此属性值可以通过调用定义的公共方法 getCurrentDateTime() 得到。

    下面再来定义程序入口文件:

    //main.cpp
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "applicationdata.h"
    
    int main(int argc, char *argv[])
    {
        qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
    
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        ApplicationData data;
        engine.rootContext()->setContextProperty("currentDateTime", &data);
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    

    在 QML 引擎装载 QML 文件前,先将类 ApplicationData 的对象指针设置到上下文中。

    下面再看看怎么调用指针对应的类对象。

    //main.qml
    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.VirtualKeyboard 2.4
    
    Window {
        id: window
        visible: true
        title: qsTr("Hello World")
    
        Text {
            id: name_id
            anchors.centerIn: parent
        }
    
        Connections {
            target: currentDateTime
            onSig_dataTimeUpdated: {
                name_id.text = currentDateTime.getCurrentDateTime();
            }
        }
    }
    

    使用 Connections 连接数据对象 currentDateTime 的信号,当指针对象的信号 sig_dataTimeUpdated 发射出来时,调用方法 getCurrentDateTime() 并用结果设置组件 Text 的属性 text。
    显示的效果是动态刷新时间日期数据的,这和在上下文中设置类型数据不同(不会刷新),如下图:


    动态实时

    相关文章

      网友评论

        本文标题:怎么将 C ++ 文件中的数据或对象暴露给 QML 使用?

        本文链接:https://www.haomeiwen.com/subject/ypzbrqtx.html