简体   繁体   中英

Printing a Qt property enum value as a key string

I have a QML Loader and on some event I want to print its status property, but I'm getting 0 on the console, even if I use toString() . So I need to always refer to the order of the enum values in qquickloader_p.h to know what's going on.

Any other way?

There is actually a way to get the enum key without knowing or even passing the enum name, if the following syntax suits your needs:

Info.print(loader, "status")

You can get it via this:

#include <QMetaType>
#include <QMetaProperty>
#include <QMetaEnum>
#include <QObject>
#include <QDebug>

class EnumInfo : public QObject {
    Q_OBJECT
  public slots:
    void print(QObject * obj, QString prop) {
      const QMetaObject * meta = obj->metaObject();
      int i = meta->indexOfProperty(qUtf8Printable(prop));
      if (i > -1) {
        QMetaProperty p = meta->property(i);
        if (p.isEnumType()) {
          QMetaEnum en = p.enumerator();
          qDebug() << en.name() << ":" << en.key(obj->property(p.name()).toInt());
        }
      }
    }
};

That object is best exposed to QML as a singleton, although for more casual use a context property won't be too much overhead.

The only other way would be to access that property from a C++ helper that looks up the enum's name using the metadata generated by moc. See also this answer .

ENUMs are used to make code more readable compared to the use of integers but faster than using strings for that purpose.
Their intent is mainly comparison.

If you want to have the names to it, you need to create additional structures (eg arrays) to look them up. Usually this is not necessary, so it is more efficient, not to do it.

If you look at console.log(typeof(Loader.Ready)) you will find, that the ENUM is indeed nothing more than a number - and maybe some meta object information.

Due to the MetaObject, there is a way, even though uncomfortable... The thing is, you need to know the name of the ENUM

enumspy.h

#ifndef ENUMSPY_H
#define ENUMSPY_H

#include <QObject>

class EnumSpy: public QObject
{
    Q_OBJECT
public:
    EnumSpy(QObject* parent = nullptr);

public slots:
    QString getEnumName(QObject* object, QString name, int index) const;
};

#endif // ENUMSPY_H

enumspy.cpp

#include <QMetaObject>
#include <QMetaEnum>
#include <QDebug>
#include "enumspy.h"

EnumSpy::EnumSpy(QObject* parent)
    : QObject(parent)
{

}

QString EnumSpy::getEnumName(QObject *object, QString name, int index) const
{
    const QMetaObject* meta = object->metaObject();
    QMetaEnum enm = meta->enumerator(meta->indexOfEnumerator(&name.toStdString()[0]));
    qDebug() << meta;
    return QString(enm.key(index));
}

Register it, create an object, and call the method.

Note: The name for the ENUMs of the Loader is Status myEnumSpy.getEnumName(myLoaderInstance, 'Status', 1) => "Ready"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM