2015-10-10 128 views
0

我試圖將QVariantMap轉換爲從QObject派生的自定義類,但是當涉及到設置我的枚舉類型的屬性時,我從得到返回值false。代碼低於:setProperty()返回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.cpp文件:

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; 
} 

的JSON輸入字符串上面的函數是這樣的:

"{\"ContentLength\": 100, \"type\": 2}" 

枚舉類型別的之前註冊在main funcction:

qRegisterMetaType<MessageType>("MessageType"); 

下面是本例中使用的QJson庫。我建立它在Windows上使用此.pro文件

編輯:

我剛剛發現type屬性不能被indexOfProperty()

qDebug() << "id = " << meta->indexOfProperty(name); // print -1, name = 'type' 
+0

False意味着它無法設置您要求的內容。 –

+0

是啊,我知道... – Jack

回答

1

枚舉屬性被發現只能如果變種設置類型是QStringQIntQUInt,可以看到here。因此,要成功設置枚舉屬性,變體需要是這些類型之一,而不是其他類型。 QJson解析任何無符號整數爲QULongLong,可以看到here, line 84。因此,一種方法是分叉QJson並修改代碼,以便將整數值轉換爲QIntQUInt或將枚舉值作爲字符串讀取/寫入。

此外,將語句放入assert不是一個好主意,但我認爲您只是編寫了試圖找出問題的代碼。

正如一個方面說明,根據Qt文檔,

[qRegisterMetaType]僅對每隔一個用例Q_DECLARE_METATYPE和qMetaTypeId登記的別名(類型定義)是有用的()應被代替使用。

因此在您的標題中用Q_DECLARE_METATYPE(MessageHeader::MessageType)代替qRegisterMetaType<MessageHeader::MessageType>("MessageType")將是一個合理的舉措。

+0

不幸的是,從枚舉類改爲枚舉並沒有解決。是的,我只是寫了那個代碼來試圖找出問題所在。 – Jack

+0

@Jack啊確實,無用的枚舉可以隱式轉換爲'int',而不是'int'。我完全取代了我的答案。 – Rostislav

+0

我加了重載並且移動到'Q_DECLARE_METATYPE',但仍然沒有工作 – Jack