c++ - Qt QMetaObjects 和从 QWidget 到 QObject 的转换

标签 c++ qt types casting deserialization

我正在尝试编写读取 xml 文件的代码并从此 xml 反序列化各种 qt 控件,我正在使用 QDomDocument 执行此操作,我想从我的反序列化方法中获取 QLlist。我遇到了一些麻烦,这里是模板类 (.h) 文件的一些代码:

 QList<T*> deserialize(QIODevice *input)
 {

        QList<T*> objects = QList<T*>();


        if(_deserializeObject(input, objects)) 
            return objects;

    }
    bool _deserializeObjects(QIODevice* input, QList<QObject*>& list);

我的 .cpp 文件使用反序列化方法,这里我从文件中读取控制标签:

bool Serializer::_deserializeObjects(QIODevice* input,  QList<QObject *> &objects)
{
    QDomDocument doc;
    if (!doc.setContent(input))
        return false;
    QDomElement root= doc.documentElement();

    for(int j = 0; j < root.childNodes().length();j++)
    {


         QObject* object;
         qDebug() << root.tagName();
        if(root.tagName().contains("QGroupBox"))   //  <------- Here i need to determine which control i need to process.
        {
           ????  
        }

       qDebug () << object->metaObject()->className();
       qDebug() << object->metaObject()->propertyCount();

    for(int i = 0; i < object->metaObject()->propertyCount(); i++)
    {

        object->metaObject()->cast()

        QMetaProperty prop = object->metaObject()->property(i);


            QString propName = prop.name();
             if(propName == "objectName")
                 continue;
             QDomNodeList nodeList = root.elementsByTagName(propName);
             if(nodeList.length() < 1)
                continue;
              QDomNode node = nodeList.at(0);
              QVariant value = object->property(propName.toLatin1().data());
              QString v = node.toElement().text();

              if(propName == "x")
              {
                  x = v.toInt();
              }
              else if(propName == "y")
              {
                  y = v.toInt();
              }
              else if(propName == "width")
              {
                  width = v.toInt();
              }
              else if(propName == "height")
              {
                  height = v.toInt();
              }
              if(propName == "geometry")
              {
                   continue;

              }
              object->setProperty(propName.toLatin1().data(), QVariant(v));


    }
    object->setProperty("geometry",QVariant(QRect(x,y,width,height)));
    objects.push_back(object);

    }
    return true;
}

这部分

  if(root.tagName().contains("QGroupBox"))   //  <------- Here i need to determine which control i need to process.
            {
               ????  
            }

           qDebug () << object->metaObject()->className();
           qDebug() << object->metaObject()->propertyCount();

        for(int i = 0; i < object->metaObject()->propertyCount(); i++)
        {
          ...
        }

我实际上想通过名称以某种方式获取控件的类型,所以问题是,我可以将 QGroupBox 转换为 QObject 以保存 QGroupBox 属性,以便 QObject 元对象类名称将是 QGroupBox,这样我就可以传递所有这些属性吗?因为我不想为每种控件类型制作循环。当我得到这样的结果时,我也是:

     QList<QObject *> ds = s.deserialize<Object>((QIODevice*)&f);

然后我可以在循环中传递所有 QObject 并使用 QMetaObject 类名并使用 qobject_cast 将每个对象转换为 QPushButton、QLabel 等吗?

最佳答案

QGroupBox是QObject的子类;因此每个 QGroupBox 也是一个 QObject,因此您可以随时将其视为一个。不需要显式强制转换。

在一个循环中遍历所有不同的派生自 QObject 的对象将做你想做的,前提是你调用它们的方法是虚方法(它们可能是——特别是 QObject::metaObject () 是一个虚方法,所以你的循环将得到适当的 QMetaObject 返回,即使它是通过 QObject 指针调用它们的方法)。

(顺便说一句,这个过程中令人讨厌的部分可能是您已经从 XML 中读取了对象类型的名称,现在需要实例化该类型的对象的部分。据我所知,没有好的自动方法在 C++ 中做到这一点,所以你能做的最好的事情是一个工厂函数,其中包含一个巨大的 switch 语句,对于你可能想要实例化的每种类型都有一个单独的 case)

关于c++ - Qt QMetaObjects 和从 QWidget 到 QObject 的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18360635/

相关文章:

c++ - 如何使用 GRUB 查询 BIOS?

arrays - 如何在swift中声明数组类型

scala - Scala的 “powerful”类型系统是什么?

types - 为什么 Smalltalk 有时被称为 "dynamically typed"?

regex - 使用 QRegExp 的双值正则表达式

c++ - qt中如何播放视频文件

带有浮点参数的 C++ 模板

c++ - 对 gsl 的 undefined reference

linux - 库部署与未使用的直接依赖关系

c++ - QT 5 中的 QUrl 解析