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!!!");
}
}
}