如何更新 QML 原生“日期”类型?
How can QML native `date` type be updated?
QML 提供了一个date
type that appears to be freely convertible to and from both the C++ QDate
class and the QML Date
type. The Date
type is an extension of the JS Date
type.
在 date
属性 上调用 set
方法显然是允许的,因为不会抛出错误(例如 "method missing"):
// in a QML object declaration
property date myDate: new Date()
// in a slot somewhere in the object
date.setYear(2002)
但是,日期数据没有改变;在调用 setYear
(或任何其他 set
方法)之前和之后打印日期会导致打印两次完全相同的日期字符串。
QML 文档似乎并没有对上面提供的 link 中的 date
类型说太多。
让我向您解释以下评论示例有什么问题:
class.hpp
#ifndef CLASS_HPP
#define CLASS_HPP
#include <QObject>
#include <QDateTime>
class DateCpp : public QObject
{
Q_OBJECT
public:
DateCpp();
protected:
// QML dates are QDateTime in C++, not QDate.
Q_PROPERTY(QDateTime fooDate
READ getDate
WRITE setDate
NOTIFY fooDateChanged)
QDateTime date;
QDateTime getDate() const;
void setDate(const QDateTime & d);
signals:
void dateChanged();
};
#endif
class.cpp
#include "class.hpp"
DateCpp::DateCpp() : QObject(), date() {}
QDateTime DateCpp::getDate() const
{
return this->date;
}
void DateCpp::setDate(const QDateTime & newDate)
{
this->date = newDate;
/*
* You have to tell QML that the property value has changed.
* For this, use the NOTIFY signal of the property. If you do not emit it,
* the property will not by updated on the QML side.
*/
emit fooDateChanged();
}
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "class.hpp"
int main(int argc, char ** argv)
{
QApplication a(argc, argv);
// Do not forget to declare your object to QML. ;-)
qmlRegisterType<DateCpp>("Foobar", 3, 14, "DateQML");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return a.exec();
}
main.qml
import QtQuick 2.6
import Foobar 3.14
Rectangle {
id: rect
// A QML date (treated as a QDateTime by the engine).
property date rectDate
/*
* Binded to myDate.fooDate, but variables are at different memory spaces.
* Will be changed together nontheless.
*/
property date rd2: myDate.fooDate
/*
* Just like rd2 but it is the same object in memory, a kind of pointer
* on DateCpp::date.
*/
property alias rd3: myDate.fooDate
// No "=" but ":" for property declarations.
property date aDateProp: Date.now()
DateQML {
id: myDate
// It is a kind of slot connected to the fooDate Q_PROPERTY's NOTIFY signal.
onFooDateChanged: {
console.log("The foodate is: " + myDate.fooDate);
// Will trigger a signal and "onRectDateChanged" will be executed.
rect.rectDate = myDate.fooDate;
}
}
MouseArea {
anchors.fill: parent
onClicked: {
/*
* It is JavaScript. "date d" is consequently wrong here.
* d will be a QML date (treated as a QDateTime by the engine).
*/
var d = Date.now();
d.setYear(2002);
// Calls the fooDate Q_PROPERTY's WRITE method, i.e. DateCpp::setDate();.
myDate.fooDate = d;
/*
* If DateCpp::setDate(); is not called here, you can still copy
* the property to modify what you want:
*
* var d2 = myDate.fooDate;
* d2.setYear(2025);
* myDate.fooDate = d2;
*/
myDate.fooDate.setYear(2025);
}
}
onRectDateChanged: {
console.log("The QML property has changed: " + rect.rectDate);
}
}
TL;DR:
- 您正在处理
QDateTime
s。
- 使用NOTIFY信号告诉系统值已经改变。
- 没有
date d
在 JavaScript 中声明日期。
- QML 属性声明中没有任何“
=
”,而是“:
”。
看来(air-dex 的回答似乎证实了)date
类型根本无法以这种方式直接修改。这是奇怪,因为尝试调用这些方法时没有错误。
因此解决方案是简单地将以后必须修改的日期对象声明为 var
而不是 date
。
QML 提供了一个date
type that appears to be freely convertible to and from both the C++ QDate
class and the QML Date
type. The Date
type is an extension of the JS Date
type.
在 date
属性 上调用 set
方法显然是允许的,因为不会抛出错误(例如 "method missing"):
// in a QML object declaration
property date myDate: new Date()
// in a slot somewhere in the object
date.setYear(2002)
但是,日期数据没有改变;在调用 setYear
(或任何其他 set
方法)之前和之后打印日期会导致打印两次完全相同的日期字符串。
QML 文档似乎并没有对上面提供的 link 中的 date
类型说太多。
让我向您解释以下评论示例有什么问题:
class.hpp
#ifndef CLASS_HPP
#define CLASS_HPP
#include <QObject>
#include <QDateTime>
class DateCpp : public QObject
{
Q_OBJECT
public:
DateCpp();
protected:
// QML dates are QDateTime in C++, not QDate.
Q_PROPERTY(QDateTime fooDate
READ getDate
WRITE setDate
NOTIFY fooDateChanged)
QDateTime date;
QDateTime getDate() const;
void setDate(const QDateTime & d);
signals:
void dateChanged();
};
#endif
class.cpp
#include "class.hpp"
DateCpp::DateCpp() : QObject(), date() {}
QDateTime DateCpp::getDate() const
{
return this->date;
}
void DateCpp::setDate(const QDateTime & newDate)
{
this->date = newDate;
/*
* You have to tell QML that the property value has changed.
* For this, use the NOTIFY signal of the property. If you do not emit it,
* the property will not by updated on the QML side.
*/
emit fooDateChanged();
}
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "class.hpp"
int main(int argc, char ** argv)
{
QApplication a(argc, argv);
// Do not forget to declare your object to QML. ;-)
qmlRegisterType<DateCpp>("Foobar", 3, 14, "DateQML");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return a.exec();
}
main.qml
import QtQuick 2.6
import Foobar 3.14
Rectangle {
id: rect
// A QML date (treated as a QDateTime by the engine).
property date rectDate
/*
* Binded to myDate.fooDate, but variables are at different memory spaces.
* Will be changed together nontheless.
*/
property date rd2: myDate.fooDate
/*
* Just like rd2 but it is the same object in memory, a kind of pointer
* on DateCpp::date.
*/
property alias rd3: myDate.fooDate
// No "=" but ":" for property declarations.
property date aDateProp: Date.now()
DateQML {
id: myDate
// It is a kind of slot connected to the fooDate Q_PROPERTY's NOTIFY signal.
onFooDateChanged: {
console.log("The foodate is: " + myDate.fooDate);
// Will trigger a signal and "onRectDateChanged" will be executed.
rect.rectDate = myDate.fooDate;
}
}
MouseArea {
anchors.fill: parent
onClicked: {
/*
* It is JavaScript. "date d" is consequently wrong here.
* d will be a QML date (treated as a QDateTime by the engine).
*/
var d = Date.now();
d.setYear(2002);
// Calls the fooDate Q_PROPERTY's WRITE method, i.e. DateCpp::setDate();.
myDate.fooDate = d;
/*
* If DateCpp::setDate(); is not called here, you can still copy
* the property to modify what you want:
*
* var d2 = myDate.fooDate;
* d2.setYear(2025);
* myDate.fooDate = d2;
*/
myDate.fooDate.setYear(2025);
}
}
onRectDateChanged: {
console.log("The QML property has changed: " + rect.rectDate);
}
}
TL;DR:
- 您正在处理
QDateTime
s。 - 使用NOTIFY信号告诉系统值已经改变。
- 没有
date d
在 JavaScript 中声明日期。 - QML 属性声明中没有任何“
=
”,而是“:
”。
看来(air-dex 的回答似乎证实了)date
类型根本无法以这种方式直接修改。这是奇怪,因为尝试调用这些方法时没有错误。
因此解决方案是简单地将以后必须修改的日期对象声明为 var
而不是 date
。