Qml调用C++方法之自定义属性

2 篇文章 0 订阅

前言

上一篇大概大致针对Qml调用C++ 方法进行了一个入门,方式可以大致分成注册和暴露两种方法。每种方式的优劣性必须根据开发的实际情况进行探究,但注册法是我认为更适用界面和逻辑分离的一种方法。

QMl之Q_PROPERTY

Q_PROPERTY这个自定属性,大家肯定不陌生。简单说一下,这里就不作深入讲解。

Q_PROPERTY(type name      # 属性
   READ getFunction     # 读取属性值,返回属性的类型的值or指针or引用
   [WRITE setFunction]   # 设置属性值,至少具有一个参数
   [RESET resetFunction]   # 设置属性的值到默认值
   [NOTIFY notifySignal]   # 属性的值发生改变时发出信号
   [CONSTANT]              # 属性的值是不变的
   [FINAL]                 # 属性不能被派生类所重写,有些情况下,这可以用于效率优化,但不是被moc强制的
   [DESIGNABLE bool]      # 此属性是否在界面设计器的属性编辑器中出现(忽略)
   [SCRIPTABLE bool]       # 属性是否可以被一个脚本引擎操作(忽略)
   [STORED bool]           # 属性是否被认为是独立存在还是依赖于其它的值而存在(忽略)
   [USER bool])            # 属性是否被设计为面向用户的或用户可修改的类属性(忽略)
  • C++ 类
//==========================QTestData.h==============================//
#pragma once
#include <QObject>
class QTestData : public QObject {
  Q_OBJECT
  Q_PROPERTY(QString name READ getName WRITE setName NOTIFY NameChanged)
 public:
  QTestData(QObject *parent=nullptr);
  ~QTestData();
  QString getName();
  void setName(QString name);
 signals:
  void NameChanged(QString name);
 private:
  QString name_;
};
//==========================QTestData.cpp==============================//
#include "QTestData.h"
#include <QDebug>
QTestData::QTestData(QObject *parent) : QObject(parent) {
  connect(this, &QTestData::NameChanged, this, [this](QString name) {
    qDebug() << "sigNameChanged new_name=" << name;
  });
}
QTestData::~QTestData() {}
QString QTestData::getName() {
  qDebug() << __FUNCTION__;
 return name_;
}
void QTestData::setName(QString name) {
  qDebug() << __FUNCTION__;
  if (name_ == name) {
    return;
  }
  name_ = name;
  emit NameChanged(name);
}

  • 调用方法暴露法(setContextProperty)or注册法(qmlRegisterType)
//==========================注册调用==============================//
{
  qmlRegisterType<QTestData>("test.conrtrol", 1, 1, "CppTestData");
  QQuickWidget *qml_widget = new QQuickWidget();
  qml_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
  qml_widget->setSource(QUrl("signal_qml.qml"));
  qml_widget->show();
  ui.verticalLayout->addWidget(qml_widget);
}
//==========================暴漏调用==============================//
//略
  • Qml实现释义(以注册法为例)
  1. 定义一个Cpp注册的类型CppTestData
  2. 如果有Cpp有信号,则把对应的信号,加上"on"前缀,则自动实现了Qml中对应的槽函数(如:NameChanged ->onNameChanged)
  3. 在槽函数中进行更新UI
import QtQuick 2.12
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Styles 1.4
import test.conrtrol 1.1
Rectangle {
    color: "gray"
    radius:10
    CppTestData {
        id: cpp_data
        onNameChanged: {
            console.log("onNameChanged ", name)
            background_image.source=name
        }
    }

    Image {
        id:background_image
        anchors.fill: parent
        fillMode: Image.PreserveAspectCrop
        source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
        antialiasing: true
    }
    Button {
        text: "Left"
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.leftMargin:50
        background: Rectangle {
            color:"#0b81ff"
            implicitWidth: 100;
            implicitHeight: 50;
            radius: 6;
        }
        //信号槽连接
        onClicked: {
            cpp_data.NameChanged("http://image.nbd.com.cn/uploads/articles/images/673466/500352700_banner.jpg")
            console.log("我被点击了"+text)
        }
    }
    Button {
        text: "Right"
        anchors.bottom: parent.bottom
        anchors.right:  parent.right
        anchors.rightMargin:50
        background: Rectangle {
            color:"#0b81ff"
            implicitWidth: 100;
            implicitHeight: 50;
            radius: 6;
        }
        //信号槽连接
        onClicked: {
            cpp_data.name="http://image.nbd.com.cn/uploads/articles/images/673466/500352700_banner.jpg"
            console.log("我被点击了"+text)
        }
    }
}

深入思考

在Qml中什么样的C++类型接口才能被调用?
  • Q_INVOKABLE 宏修饰
  • Q_PROPERTY修饰的元对象系统访问的属性
  • 信号( signals)或槽函数(public slots)

总结:元对象系统可识别的方法

在Qml能识别的C++类关键点?
  • QObject 的派生类
  • 必须有Q_OBJECT 宏

两个条件是C++ 类被Qt的元对象系统的识别的关键!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值