Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ setProperty()返回false_C++_Json_Qt_Deserialization_Moc - Fatal编程技术网

C++ setProperty()返回false

C++ setProperty()返回false,c++,json,qt,deserialization,moc,C++,Json,Qt,Deserialization,Moc,我试图将QVariantMap转换为从QObject派生的自定义类,但在设置枚举类型的属性时,我得到了false的返回值。代码如下: MessageHeader.h文件: // deserialization class header class MessageHeader : public QObject { Q_OBJECT public: MessageHeader(QObject *parent = 0); ~MessageHeader(); enum

我试图将
QVariantMap
转换为从
QObject
派生的自定义类,但在设置枚举类型的属性时,我得到了
false
的返回值。代码如下:

MessageHeader.h文件:

// deserialization class header
class MessageHeader : public QObject
{
    Q_OBJECT

public:
    MessageHeader(QObject *parent = 0);
    ~MessageHeader();

    enum class MessageType
    {
        none = 0,
        foo = 1,
        baa = 2
    };

    Q_ENUM(MessageType)
    Q_PROPERTY(MessageType type READ getType WRITE setType)
    Q_PROPERTY(int ContentLength READ getContentLength WRITE setContentLength)

    void setType(MessageType type);
    void setContentLength(int ContentLength);
    MessageType getType();
    int getContentLength();
    QString toString();

    MessageType type = MessageType::none;
    int ContentLength = 0;
};
MessageHeader::MessageHeader(QObject *parent)
    : QObject(parent)
{
}

MessageHeader::~MessageHeader()
{
}

MessageType MessageHeader::getType()
{
    return type;
}

int MessageHeader::getContentLength()
{
    return ContentLength;
}

void MessageHeader::setType(MessageType type)
{
    this->type = type;
}

void MessageHeader::setContentLength(int ContentLength)
{
    this->ContentLength = ContentLength;
}

QString MessageHeader::toString()
{
    return QString("NOT IMPLEMENTED YET");
}
MessageHeader.cpp文件:

// deserialization class header
class MessageHeader : public QObject
{
    Q_OBJECT

public:
    MessageHeader(QObject *parent = 0);
    ~MessageHeader();

    enum class MessageType
    {
        none = 0,
        foo = 1,
        baa = 2
    };

    Q_ENUM(MessageType)
    Q_PROPERTY(MessageType type READ getType WRITE setType)
    Q_PROPERTY(int ContentLength READ getContentLength WRITE setContentLength)

    void setType(MessageType type);
    void setContentLength(int ContentLength);
    MessageType getType();
    int getContentLength();
    QString toString();

    MessageType type = MessageType::none;
    int ContentLength = 0;
};
MessageHeader::MessageHeader(QObject *parent)
    : QObject(parent)
{
}

MessageHeader::~MessageHeader()
{
}

MessageType MessageHeader::getType()
{
    return type;
}

int MessageHeader::getContentLength()
{
    return ContentLength;
}

void MessageHeader::setType(MessageType type)
{
    this->type = type;
}

void MessageHeader::setContentLength(int ContentLength)
{
    this->ContentLength = ContentLength;
}

QString MessageHeader::toString()
{
    return QString("NOT IMPLEMENTED YET");
}
和反序列化函数模板帮助器:

  template<typename T>
    T* Deserialize(const QString &json)
    {
        bool status = false;

        QJson::Parser parser;
        QVariantMap map = parser.parse(json.toUtf8(), &status).toMap();

        if(!status)
            return NULL;

        T *obj = new T(); //don't worry about this, I'll rather take this from paramters once this is working
        QObject *p = (QObject *) obj; // cast done so that I see setProperty() method
        for(QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
        {
            const char *name = iter.key().toLatin1();
            const QVariant value = iter.value();
            qDebug() << "setting " << name << "=" << value;
            // the issue goes below. Here setProperty() return false.
            // At this point, name = 'type' and value = 2
            assert(p->setProperty(name, value));
        }
    //QJson::QObjectHelper::qvariant2qobject(map, obj);
    return obj;
}
枚举类型先在
main
函数中注册,然后再执行其他操作:

qRegisterMetaType<MessageType>("MessageType");
qRegisterMetaType(“MessageType”);
这是本例中使用的库。我用这个文件在Windows上构建它

编辑:

我刚刚发现无法通过找到类型属性


qDebug()只有当变量类型为
QString
QInt
QUInt
时,才能设置枚举属性。因此,要成功设置enum属性,变量必须是这些类型之一,而不是其他类型。QJson将任何无符号整数解析为
qlonglong
,如图所示。因此,一种方法是分叉QJson并修改代码,以便将整数值转换为
QInt
QUInt
或将枚举值作为字符串读/写

另外,将语句放在
断言中并不是一个好主意,但我假设您编写的代码只是为了解决问题

作为旁注,根据Qt文档

[qRegisterMetaType]仅用于为每个其他用例注册别名(typedef)Q_DECLARE_元类型,应改用qMetaTypeId()


因此,将标题中的
qRegisterMetaType(“MessageType”)
替换为
Q\u DECLARE\u METATYPE(MessageHeader::MessageType)
将是一个合理的选择。

以罗斯蒂斯拉夫的答案为基础,如果你别无选择,只能收到一个
QULongLong
作为输入,如果要设置的属性是枚举,请使用以下代码段对其进行转换:

#include <QMetaProperty>

const QMetaObject* meta = object->metaObject();
const int index = meta->indexOfProperty(propName);
if (index == -1) {/* report error*/}
if (meta->property(index).isEnumType())
    // special case for enums properties: they can be set from QInt or QUInt variants,
    // but unsigned integers parsed from json are QULongLong
    object->setProperty(propName, propVariant.value<unsigned int>());
else
    object->setProperty(propName, propVariant);
#包括
常量QMetaObject*meta=object->metaObject();
const int index=meta->indexOfProperty(propName);
如果(索引==-1){/*报告错误*/}
if(meta->property(index.isEnumType())
//枚举属性的特殊情况:它们可以从QInt或QUInt变量设置,
//但是从json解析的无符号整数是QULongLong
对象->设置属性(propName,propVariant.value());
其他的
对象->设置属性(propName,propVariant);

False表示它无法设置您要求它设置的内容。不幸的是,从enum类更改为enum并不能解决此问题。是的,我只是写了那段代码试图找出问题。@Jack啊,事实上,非作用域枚举是隐式转换为
int
,而不是从
int
。我完全替换了我的答案。我添加了重载并移动到
Q\u DECLARE\u元类型
,但仍然没有work@Jack嗯,我实际上在我的机器上测试了这种方法。您使用的是哪种编译器和Qt版本?我在VS 2013中测试了Qt 5.4。嗯,我最后一次回答的时候已经是凌晨4点了。事实上,即使没有超负荷,它对我也有效。请参阅我使用的源文件和标题。我的输出是“12”。我查看了生成的
moc
文件,其中的代码是
setType(*reinterpret_cast(_v))。因此,为了确保安全,我通过编写
enum类MessageType:int
明确指定了枚举的底层类型。然而,如果没有它,它对我也很有效。你能把你的moc文件显示的内容贴出来吗?