Reputation: 1376
I have currently a problem when using an own type as property type.
My custom type is defined within a namespace. When I put it into the global namespace, everything works without any problems.
Is it possible to use custom types within a namespace as property values?
Here's a minimum example (I am using Qt5.0 and g++ 4.7.3)
Here's the test.pro
file:
LANGUAGE = C++
QT += core gui widgets
TARGET = test
QMAKE_CXXFLAGS += -std=c++11
HEADERS += test.h
SOURCES += test.cpp
Here's the test.h
file:
#include <QtCore>
#include <QtGui>
#include <QtWidgets>
namespace MyNamespace
{
struct MyValue
{
private:
QString a;
int b;
public:
MyValue(const QString &a="", int b=0)
: a(a), b(b)
{
}
bool operator !=(const MyValue &other) const
{
return (this->a!=other.a) || (this->b!=other.b);
}
friend QDataStream &operator<<(QDataStream &stream, const MyNamespace::MyValue &value);
friend QDataStream &operator>>(QDataStream &stream, MyNamespace::MyValue &value);
friend QDebug operator<<(QDebug debug, const MyNamespace::MyValue &value);
};
inline QDataStream &operator<<(QDataStream &stream, const MyNamespace::MyValue &value)
{
stream << value.a;
return stream << value.b;
}
inline QDataStream &operator>>(QDataStream &stream, MyNamespace::MyValue &value)
{
stream >> value.a;
return stream >> value.b;
}
inline QDebug operator<<(QDebug debug, const MyNamespace::MyValue &value)
{
return debug << "MyValue("<<value.a<<", "<<value.b<<")";
}
}
Q_DECLARE_METATYPE(MyNamespace::MyValue)
namespace AnotherNamespace
{
typedef MyNamespace::MyValue MyValue;
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(MyValue value READ value WRITE setValue NOTIFY valueChanged)
public:
MyValue value()
{
return value_;
}
public slots:
void setValue(const MyValue &value)
{
if(this->value() != value)
{
value_ = value;
emit valueChanged(value);
}
}
signals:
void valueChanged(const MyValue &value);
private:
MyValue value_;
};
}
And here's the test.cpp file:
#include "test.h"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
qRegisterMetaTypeStreamOperators<MyNamespace::MyValue>("MyNamespace::MyValue");
AnotherNamespace::MyClass myObject;
myObject.setValue(MyNamespace::MyValue("the answer", 42));
QMetaObject metaObject = AnotherNamespace::MyClass::staticMetaObject;
QMetaProperty metaProperty = metaObject.property(metaObject.indexOfProperty("value"));
QVariant variant = metaProperty.read(&myObject);
MyNamespace::MyValue value = variant.value<MyNamespace::MyValue>();
qDebug() << value;
qDebug() << "\nIt's interesting, that this is working without problems:";
variant = QVariant::fromValue(MyNamespace::MyValue("2^4", 16));
value = variant.value<MyNamespace::MyValue>();
qDebug() << value;
return 0;
}
The output of this minimum example is
QMetaProperty::read: Unable to handle unregistered datatype 'MyValue' for property 'AnotherNamespace::MyClass::value'
MyValue( "" , 0 )
It's interesting, that this is working without problems:
MyValue( "2^4" , 16 )
As alreaday said, after removing any namespace usage from the minimum example, everything works without any problems with the following output
MyValue( "the answer" , 42 )
It's interesting, that this is working without problems:
MyValue( "2^4" , 16 )
Upvotes: 3
Views: 2132
Reputation: 1376
While typing in the question I've found the answer. The error is in the following lines
// ...
namespace AnotherNamespace
{
typedef MyNamespace::MyValue MyValue;
class MyClass : public QObject
{
Q_OBJECT
Q_PROPERTY(MyValue value READ value WRITE setValue NOTIFY valueChanged)
// ...
When using the Q_PROPERTY
I have to give the full typename with all namespaces noted. So instead of using
Q_PROPERTY(MyValue value READ value WRITE setValue NOTIFY valueChanged)
I have to use
Q_PROPERTY(MyNamespace::MyValue value READ value WRITE setValue NOTIFY valueChanged)
the Qt Property system doesn't seem to recognize typedefs.
Upvotes: 5