Explicación detallada del tipo de datos universal QVariant de Qt6

QVariant, conocido como el tipo de datos universal, es en realidad un tipo de unión conjunta similar a C++. En pocas palabras, un fuerte rendimiento de personalización es como una caja que le permite colocar casi cualquier tipo de qt y, al mismo tiempo, puede construir fácilmente cualquier estructura de datos compleja de cualquier tipo, pero tenga en cuenta que los tipos complejos implican compromisos en el rendimiento y la eficiencia. .

qt6 se describe en la documentación de la siguiente manera:

Dado que C++ prohíbe que las uniones contengan tipos con constructores o destructores no predeterminados, muchas clases heredadas no se pueden usar en uniones. Si no hay QVariant, esto será un problema para QObject::property () y el trabajo de la base de datos, por lo que se introduce este tipo.

1. Por qué existe un tipo QVariant

Después de la prueba, en realidad es "No se permite que los objetos miembro en una unión tengan constructores personalizados" 

//El siguiente código reporta un error

#include <iostream>
class Greeting {
    int a;
    char b;
    Greeting (){}
};

typedef union _uni {
    Greeting  s;
}uni; 

int main(void)
{
    uni u;

    return 0;
}

 2. QVariant admite tipos comunes

Nota: Type type() se eliminó en qt6, *.type() ya no se puede usar y *.typeName() se puede usar para generar el nombre del tipo;

Es compatible con casi todos los tipos comunes en qt y puede guardar fácilmente muchos tipos de valores durante el uso, que es un poco como una caja, simplemente colóquelo.

QVariant str1("让世界爱上中国造!");
    if(str1.canConvert<QString>())
    {
        qDebug()<<"str1 is QString type";
    }

    qDebug()<<"str1 tostring type="<<str1.toString();
    qDebug()<<"str1 to int type="<<str1.toInt();

    QList<int> intList = {7, 11, 42};
    QVariant variant = QVariant::fromValue(intList);
    if (variant.canConvert<QVariantList>())
    {
        QSequentialIterable iterable = variant.value<QSequentialIterable>();
        QSequentialIterable::const_iterator it = iterable.begin();
        const QSequentialIterable::const_iterator end = iterable.end();
        for ( ; it != end; ++it) {
            qDebug() << *it;
        }
    }

 Como se muestra en la figura anterior, cuando se usa canConvert<type name>() generalmente se usa para juzgar si se puede convertir a este tipo, o se puede llamar a la función de conversión correspondiente toInt() para convertir directamente la salida, y si el la conversión falla, será 0;

 3. Tipos personalizados admitidos por QVariant

En el pasado, la personalización requería Q_DECLARE_METATYPE para registrarse, pero ahora no es necesario;

 En resumen, QVariant es muy flexible y puede admitir tipos existentes y tipos personalizados, pero cualquier estructura de datos compleja de cualquier tipo significa un compromiso en el rendimiento y la eficiencia.

Supongo que te gusta

Origin blog.csdn.net/yanchenyu365/article/details/130721388
Recomendado
Clasificación