Qt C++属性类型提供给 QML调用(一)

概述

由于QML引擎与Qt元对象系统的紧密集成,任何由QObject派生出来的类其公有的接口或属性都可以从QML代码中轻松访问,并且改动的地方很少,就可以让C++代码定义的功能轻松扩展QML。

任何QML代码都可以访问QObject派生类的实例的以下成员:

  • 属性
  • 方法(用Q_INVOKABLE标记)
  • 信号

另外,如果用Q_ENUMS声明了枚举,那么枚举也是可以直接调用的。
通常来说,QObject类派生于QML类型系统中,都可以从QML访问,但是如果要访问其他类型信息的方式使用某个类,例如,如果该类本身将用作方法参数或属性,那么该类需要注册才能使用,后期将会写相关的文章进行介绍。

Q_PROPERTY()

要想在 QML中调用到 C++的属性,就需要用到Q_PROPERTY宏,该宏就是将 C++属性暴露给QML 调用。
下面来看个简单示例:
首先新建一个类继承于 QObject

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ getName WRITE setName NOTIFY sigNameChanged)
public:
    explicit Student(QObject *parent = nullptr);
    ~Student(){}

    void setName(const QString & name){
        if(name != m_name){
            m_name = name;
            emit sigNameChanged(m_name);
        }
    }
    QString getName() const {return m_name;}
signals:
    void sigNameChanged(QString name);

private:
    QString m_name;
};

该类中用Q_PROPERTY宏将 name 属性暴露出来供 QML 调用。

然后在 main 函数中进行上下文属性注册

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

    QQmlApplicationEngine engine;
    Student student;
    engine.rootContext()->setContextProperty("student", &student);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

然后在 QML 中进行调用

Window {
    visible: true
    width: 640
    height: 480

    Label{
        anchors.centerIn: parent
        text: student.name
    }

    Connections{
        target: student
        onSigNameChanged:{
            console.log("student name changed",name)
        }
    }
    Component.onCompleted: {
        student.name = "xiaoming"
    }
}

为了与QML实现最大的互操作性,任何可写的属性应该有一个关联的NOTIFY信号,每当属性值发生变化时就会发出。
在页面加载完成后Component.onCompleted中去修改 student 的属性,这时候会自动触发信号sigNameChanged,这里将信号连接起来,看看输出效果:

qml: student name changed xiaoming

这就从 QML 轻松的调用到了 C++ 中的属性。

本文就只介绍将简单的 C++系统属性提供给 QML 中调用,后期将介绍更多的类型提供给 QML 使用。
本文示例代码在这里,点击下载

猜你喜欢

转载自blog.csdn.net/luoyayun361/article/details/80470829
今日推荐