summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc7
-rw-r--r--src/tools/moc/generator.cpp6
-rw-r--r--src/tools/moc/moc.cpp8
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp79
4 files changed, 77 insertions, 23 deletions
diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc
index 7276e8d86a..7ca3e25b00 100644
--- a/src/corelib/doc/src/objectmodel/properties.qdoc
+++ b/src/corelib/doc/src/objectmodel/properties.qdoc
@@ -53,7 +53,12 @@
argument, either of the property's type or a pointer or reference
to that type. e.g., QWidget::enabled has the \c WRITE function
QWidget::setEnabled(). Read-only properties do not need \c WRITE
- functions. e.g., QWidget::focus has no \c WRITE function.
+ functions. e.g., QWidget::focus has no \c WRITE function. If you specify
+ both a \c BINDABLE and \c{WRITE default}, a \c WRITE accessor will be
+ generated from the \c BINDABLE. The generated \c WRITE accessor will \e not
+ explicitly emit any signal declared with \c NOTIFY. You should register
+ the signal as change handler to the \c BINDABLE, for example using
+ \l{Q_OBJECT_BINDABLE_PROPERTY}.
\li A \c MEMBER variable association is required if no \c READ accessor
function is specified. This makes the given member variable
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index f030bc8918..0e8ba0bb72 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -1315,6 +1315,12 @@ void Generator::generateStaticMetacall()
if (cdef->enumDeclarations.value(p.type, false)) {
fprintf(out, " case %d: %s%s(QFlag(*reinterpret_cast<int*>(_v))); break;\n",
propindex, prefix.constData(), p.write.constData());
+ } else if (p.write == "default") {
+ fprintf(out, " case %d: {\n", propindex);
+ fprintf(out, " %s%s().setValue(*reinterpret_cast< %s*>(_v));\n",
+ prefix.constData(), p.bind.constData(), p.type.constData());
+ fprintf(out, " break;\n");
+ fprintf(out, " }\n");
} else if (!p.write.isEmpty()) {
fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n",
propindex, prefix.constData(), p.write.constData(), p.type.constData());
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index a14f0c1ccd..8a5abd3020 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -1301,7 +1301,7 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
error(1);
} else if (test(DEFAULT)) {
v = lexem();
- if (l != "READ")
+ if (l != "READ" && l != "WRITE")
error(1);
} else {
next(IDENTIFIER);
@@ -1387,6 +1387,12 @@ void Moc::parsePropertyAttributes(PropertyDef &propDef)
propDef.read = "";
warning(msg.constData());
}
+ if (propDef.write == "default" && propDef.bind.isNull()) {
+ const QByteArray msg = "Property declaration " + propDef.name
+ + " is not BINDable but default-WRITEable. WRITE will be ignored.";
+ propDef.write = "";
+ warning(msg.constData());
+ }
}
void Moc::parseProperty(ClassDef *def)
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index 97575f5bb7..48249eec0c 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -744,7 +744,7 @@ private slots:
void observerMetaCall();
void setQPRopertyBinding();
void privateQPropertyShim();
- void readThroughBindable();
+ void readWriteThroughBindable();
signals:
void sigWithUnsignedArg(unsigned foo);
@@ -4339,7 +4339,7 @@ void tst_Moc::privateQPropertyShim()
class BindableOnly : public QObject
{
Q_OBJECT
- Q_PROPERTY(int score BINDABLE scoreBindable READ default)
+ Q_PROPERTY(int score BINDABLE scoreBindable READ default WRITE default)
public:
BindableOnly(QObject *parent = nullptr)
: QObject(parent)
@@ -4350,27 +4350,64 @@ private:
QProperty<int> m_score;
};
-
-void tst_Moc::readThroughBindable()
+class BindableAndNotifyable : public QObject
{
- BindableOnly o;
-
- QCOMPARE(o.scoreBindable().value(), 4);
- QCOMPARE(o.property("score").toInt(), 4);
- o.scoreBindable().setValue(5);
- QCOMPARE(o.scoreBindable().value(), 5);
- QCOMPARE(o.property("score").toInt(), 5);
-
-
- const QMetaObject *mo = o.metaObject();
- const int i = mo->indexOfProperty("score");
- QVERIFY(i > 0);
-
- QMetaProperty p = mo->property(i);
- QCOMPARE(p.name(), "score");
+ Q_OBJECT
+ Q_PROPERTY(int score BINDABLE scoreBindable NOTIFY scoreChanged READ default WRITE default)
+public:
+ BindableAndNotifyable(QObject *parent = nullptr)
+ : QObject(parent)
+ , m_score(4)
+ {}
+ QBindable<int> scoreBindable() { return QBindable<int>(&m_score); }
+signals:
+ void scoreChanged();
+private:
+ QProperty<int> m_score;
+};
- QVERIFY(p.isValid());
- QCOMPARE(p.read(&o), 5);
+void tst_Moc::readWriteThroughBindable()
+{
+ {
+ BindableOnly o;
+ QCOMPARE(o.scoreBindable().value(), 4);
+ QCOMPARE(o.property("score").toInt(), 4);
+ o.scoreBindable().setValue(5);
+ QCOMPARE(o.scoreBindable().value(), 5);
+ QCOMPARE(o.property("score").toInt(), 5);
+ const QMetaObject *mo = o.metaObject();
+ const int i = mo->indexOfProperty("score");
+ QVERIFY(i > 0);
+ QMetaProperty p = mo->property(i);
+ QCOMPARE(p.name(), "score");
+ QVERIFY(p.isValid());
+ QVERIFY(p.isWritable());
+ QCOMPARE(p.read(&o), 5);
+ QVERIFY(o.setProperty("score", 6));
+ QCOMPARE(o.property("score").toInt(), 6);
+ QVERIFY(p.write(&o, 7));
+ QCOMPARE(p.read(&o), 7);
+ }
+ {
+ BindableAndNotifyable o;
+ QCOMPARE(o.scoreBindable().value(), 4);
+ QCOMPARE(o.property("score").toInt(), 4);
+ o.scoreBindable().setValue(5);
+ QCOMPARE(o.scoreBindable().value(), 5);
+ QCOMPARE(o.property("score").toInt(), 5);
+ const QMetaObject *mo = o.metaObject();
+ const int i = mo->indexOfProperty("score");
+ QVERIFY(i > 0);
+ QMetaProperty p = mo->property(i);
+ QCOMPARE(p.name(), "score");
+ QVERIFY(p.isValid());
+ QVERIFY(p.isWritable());
+ QCOMPARE(p.read(&o), 5);
+ QVERIFY(o.setProperty("score", 6));
+ QCOMPARE(o.property("score").toInt(), 6);
+ QVERIFY(p.write(&o, 7));
+ QCOMPARE(p.read(&o), 7);
+ }
}
QTEST_MAIN(tst_Moc)