En el marco de Qt, las enumeraciones permiten definir conjuntos de constantes con nombres, comúnmente empleadas para modelar estados, configuraciones o como parámetros en señales y ranuras. Qt extiende la funcionalidad estándar de C++ mediante integración con su sistema de meta-objetos, facilitando la conversión entre valores enumerados y cadenas.
Dfeinición Básica de Enumeraciones
Para declarar una enumeración dentro de una clase QObject, se sigue el siguiente patrón:
class Gestionador : public QObject {
Q_OBJECT
public:
enum ModoOperativo {
ModoReposo,
ModoActividad,
ModoFinalizado
};
void establecerModo(ModoOperativo modo);
};
El uso de esta enumeración en código es directo:
Gestionador gestor;
gestor.establecerModo(Gestionador::ModoActividad);
Integración con el Sistema de Meta-Objetos
Al registrar una enmueración con la macro Q_ENUM (disponible desde Qt 5.5), se habilita la introspección mediante QMetaEnum. Esto permite convertir valores a cadenas y viceversa.
class Gestionador : public QObject {
Q_OBJECT
public:
enum ModoOperativo {
ModoReposo,
ModoActividad,
ModoFinalizado
};
Q_ENUM(ModoOperativo)
};
Conversión entre Valores y Cadenas
A continuación, un ejemplo que muestra cómo transformar un valor de enumeración a su representación textual y recuperarlo posteriormente:
#include <QMetaEnum>
// Conversión de valor a cadena
Gestionador::ModoOperativo modoActual = Gestionador::ModoActividad;
QMetaEnum reflejo = QMetaEnum::fromType<Gestionador::ModoOperativo>();
QString nombreModo = reflejo.valueToKey(modoActual); // Resultado: "ModoActividad"
// Conversión de cadena a valor
int valorNumerico = reflejo.keyToValue("ModoFinalizado"); // Resultado: 2
Implementación de Funciones de Conversión Genérica
Para mayor flexibilidad, se pueden crear métodos utilitarios que manejen diferentes enumeraciones:
#include <QObject>
#include <QMetaEnum>
class AyudanteConversion : public QObject
{
Q_OBJECT
public:
enum class EstadoProceso {
Inactivo = 1,
EnProceso,
Completado,
Error,
Desconocido
};
Q_ENUM(EstadoProceso)
// Convertir enumeración a cadena
template<typename TipoEnum>
static QString aCadena(const QString& nombreEnum, TipoEnum valor)
{
const QMetaObject& metaObj = AyudanteConversion::staticMetaObject;
for (int idx = 0; idx < metaObj.enumeratorCount(); ++idx) {
QMetaEnum metaEnum = metaObj.enumerator(idx);
if (QString(metaEnum.name()) == nombreEnum) {
const char* clave = metaEnum.valueToKey(static_cast<int>(valor));
return clave ? QString(clave) : QString("ValorNoVálido");
}
}
return QString("EnumNoEncontrado");
}
// Convertir cadena a enumeración
template<typename TipoEnum>
static TipoEnum desdeCadena(const QString& nombreEnum, const QString& clave, TipoEnum defecto)
{
const QMetaObject& metaObj = AyudanteConversion::staticMetaObject;
for (int idx = 0; idx < metaObj.enumeratorCount(); ++idx) {
QMetaEnum metaEnum = metaObj.enumerator(idx);
if (QString(metaEnum.name()) == nombreEnum) {
bool exito = false;
int numValor = metaEnum.keyToValue(clave.toUtf8().constData(), &exito);
if (exito)
return static_cast<TipoEnum>(numValor);
}
}
return defecto;
}
};
Ejemplo de uso:
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QString texto = AyudanteConversion::aCadena("EstadoProceso", AyudanteConversion::EstadoProceso::Inactivo);
qDebug() << "Cadena obtenida:" << texto;
AyudanteConversion::EstadoProceso estado = AyudanteConversion::desdeCadena<AyudanteConversion::EstadoProceso>("EstadoProceso", texto, AyudanteConversion::EstadoProceso::Desconocido);
qDebug() << "Valor recuperado:" << estado;
return app.exec();
}