Q_PROPERTY 中notify关键词使用

The Property System属性系统介绍:

A NOTIFY signal is optional. If defined, it should specify one existing signal in that class that is emitted whenever the value of the property changes. NOTIFY signals for MEMBER variables must take zero or one parameter, which must be of the same type as the property. The parameter will take the new value of the property. The NOTIFY signal should only be emitted when the property has really been changed, to avoid bindings being unnecessarily re-evaluated in QML, for example. Qt emits automatically that signal when needed for MEMBER properties that do not have an explicit setter. 

NOTIRY是可选的,它指定一个信号函数,只要属性变化,那么该类就要发出信号。使用MEMBER修饰的变量,信号要么0个,要么1个与变量类型相同的参数,NOTIFY信号,只因该在变量值变化后发出。避免在QML中绑定重复的评估(大概意思属性绑定的重复更新),例如通过MEMBER修饰,且没有显示的设置函数(WRITER),那么Qt将会自动发出NOTIFY信号。

实践过程中:
使用MEMBER,且没有使用WRITER,发现,QML能主动发出NOTIFY信号。但c++类中,不能主动发出NOTIFY信号。

代码:

#ifndef SIMPLE_H
#define SIMPLE_H
#include <QObject>

class Simple : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name MEMBER m_name NOTIFY nameChanged)
public:
    explicit Simple(QObject *parent = nullptr);
public:
//    QString name(){ return m_name;}
//    void setName(QString name)
//    {


//            m_name = name;
//            //emit nameChanged(name);


//    }
public slots:
    void slotNameChanged(QString name);
    void slotTimeOut();
signals:
    void nameChanged(QString name);
private:
    QString m_name;

};





#endif // SIMPLE_H


#include "Simple.h"
#include "QDebug"
#include <QTimer>
Simple::Simple(QObject *parent)
    : QObject{parent}
{
     m_name = "hello";
    connect(this,SIGNAL(nameChanged(QString)),this,SLOT(slotNameChanged(QString)));
    QTimer *timer = new QTimer(this);
    timer->setInterval(2000);
    connect(timer,SIGNAL(timeout()),this,SLOT(slotTimeOut()));
    timer->start();

}

void Simple::slotNameChanged(QString name)
{
    qDebug() << "name Changed name"  << name;
}
void Simple::slotTimeOut()
{
    qDebug() << "slotTimeOut!!!"  << m_name;
    m_name = "world";
    emit nameChanged(m_name);
}

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "Simple.h"

int main(int argc, char *argv[])
{
    qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    Simple *simple = new Simple();
    engine.rootContext()->setContextProperty("Simple",simple);
    const QUrl url(u"qrc:/untitled1/main.qml"_qs);
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}
//main.xml

import QtQuick
import QtQuick.VirtualKeyboard
import QtQuick.Controls
import QtQuick.Layouts

Window {
    id: window
    width: 300
    height: 300
    visible: true
    title: Simple.name
    Button
    {
        anchors.fill:parent
        onClicked:
        {
            Simple.name = "hello";
            console.log("click!!!");
        }
    }


}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 是的,Q_PROPERTYNOTIFY功能可以用来在QT属性值发生改变时发出信号。 首先,你需要在Q_PROPERTY使用NOTIFY选项,指定一个信号名称,例如: ``` Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) ``` 然后,你需要在类实现这个信号,例如: ``` signals: void valueChanged(int newValue); ``` 最后,你可以在属性值发生改变时使用emit关键字来发出信号,例如: ``` void setValue(int newValue) { if (m_value != newValue) { m_value = newValue; emit valueChanged(newValue); } } ``` 这样,每当调用setValue函数改变属性值时,就会发出valueChanged信号,其他对象就可以通过连接信号来接收通知并执行相应的操作。 ### 回答2: 在Qt,Q_PROPERTY用于向对象添加属性,并为属性生成getter和setter方法。NOTIFY关键字用于在属性值发生变化时发出信号。 要使Q_PROPERTYNOTIFY发送信号,首先需要在QObject派生类的头文件定义该属性并使用Q_PROPERTY宏。例如: ``` class MyClass : public QObject { Q_OBJECT Q_PROPERTY(int myProperty READ myProperty WRITE setMyProperty NOTIFY myPropertyChanged) public: int myProperty() const; void setMyProperty(int value); signals: void myPropertyChanged(); }; ``` 在上述代码,我们定义了一个名为myProperty的属性,该属性具有getter和setter方法,并且属性值变化时将发出myPropertyChanged信号。 接下来,在setter方法使用objectName::myProperty前缀调用Q_EMIT宏来发出myPropertyChanged信号。例如: ``` void MyClass::setMyProperty(int value) { if (m_myProperty != value) { m_myProperty = value; Q_EMIT myPropertyChanged(); } } ``` 在上述代码,我们首先检查新值是否与旧值相同,只有当不同时才更新属性值,并且使用Q_EMIT宏发出myPropertyChanged信号。 当myProperty属性的值在任何地方通过setter方法进行修改时,myPropertyChanged信号都会被发送,以通知相关的对象。 最后,在使用该类的地方,可以连接到myPropertyChanged信号以获取myProperty属性值的变化通知。例如: ``` MyClass myObject; QObject::connect(&myObject, SIGNAL(myPropertyChanged()), []() { qDebug() << "myProperty has changed"; }); ``` 在上述代码,我们将myPropertyChanged信号与一个lambda函数连接起来,每当myProperty属性的值发生变化时,lambda函数将被调用,并输出一条调试信息。 总结起来,要使Q_PROPERTYNOTIFY发送信号,需要在setter方法使用Q_EMIT宏发出对应的信号,并在使用该类的地方连接到对应的信号以接收属性值的变化通知。 ### 回答3: 在QT,Q_PROPERTY宏可以用于在C++类定义属性,同时还可以使用NOTIFY关键字指定属性变化时应发送的信号。 使用NOTIFY关键字时,需要在属性的setter方法手动发出信号。一种常见的做法是在setter方法调用QObject类的emitSignal方法来发送信号。例如: ```cpp private: QString m_name; public: Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) QString name() const { return m_name; } void setName(const QString& name) { if (m_name != name) { m_name = name; emit nameChanged(); } } signals: void nameChanged(); ``` 在这个例子,我们定义了一个name属性,当其值发生变化时,会发送nameChanged信号。 Q_PROPERTY使用NOTIFY关键字时,还需要为属性的getter方法和setter方法指定对应的名称(name和setName)。 需要注意的是,该属性的getter和setter方法的名称可以自定义,只需保持与Q_PROPERTY指定的名称一致即可。 因此,当使用Q_PROPERTY宏定义属性时,通过在setter方法手动发送信号,就可以使用NOTIFY关键字来发送信号了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值