[Qt-interest] Using QVariant to store enums and compare them against each other.
MARTIN Pierre
hickscorp at gmail.com
Mon Aug 8 14:10:05 CEST 2011
Hello list,
First, since i'm new to the list, here is a little something about me. i have been developing with various languages for 11 years now, and usually go with Qt for OpenSource projects as well as for with commercial application with the dual licensing system. i'm from france but i live most of the time in the US, CA. i develop mostly on unix / linux, and also use Visual Studio from times to times… But i avoid it when i can.
Here is about the problem i have now (Posted here: http://stackoverflow.com/questions/6974082/qt-enums-comparison-and-output-to-qdebug and here: http://stackoverflow.com/questions/6974082/qt-enums-comparison-and-output-to-qdebug).
The basic idea is for me to have a very generic editor for enum types (Not flags for now, just enums). This would appear as a combo box containing all of the enum values, and would allow the user to pick another one. Of course, this editor would be able to first display a value picked randomly from a previously set variable.
As a clarification: i am successful for most of the design and coding of this small piece of widget… However, my solution is looking cheesy for two reasons:
Here is the constructor of my combo box - based widget, which populates the list with a given enum type:
REA::WgtEnumItemEditor::WgtEnumItemEditor (QVariant::Type t, QWidget *p)
: QComboBox(p) {
QMetaObject const &mo = RE::E::staticMetaObject;
QString mtName = QMetaType::typeName(t);
mtName = mtName.mid(mtName.lastIndexOf(':')+1);
qint32 const iEnum = mo.indexOfEnumerator(mtName.toLatin1());
QMetaEnum const &en = mo.enumerator(iEnum);
quint32 const cEnum = en.keyCount();
for (quint32 i=0; i<cEnum; i++) {
const char *key = en.key(i);
int const val = en.value(i);
int const *pVal = &val;
QVariant const var (t, &pVal);
addItem (RE::classNameToNaturalString(key), var);
qDebug() << var;
}
connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(this_currentIndexChanged(int)));
}
As you can see, the widget takes any user type as a parameter, and hooks up to QMetaEnum values in the userData property of each list item. Here, i suspect that i use a very wrong way to construct my QVariants… This constructor usage seems to be discouraged by the docs. However, i didn't find any proper generic solution to be able to construct a valid QVariant carrying both my type and my value (e.g i don't want to construct an int QVariant, since the real type i want it to carry is of type "t", passed in the constructor parameters and would be a valid registered enum meta-type id). So i'm just passing an address of the integer value of my enum to the constructor, which then internally copies the value (Not the address, i have double checked that). It is perfectly working, but i really freel it's not clean.
Then the way the list can be set up to display an initial value is as follows:
void REA::WgtEnumItemEditor::setValue (QVariant const &v) {
for (quint32 i=0; i<count(); i++) {
if (*(int const*)itemData(i).constData()==*(int const*)v.constData()) {
setCurrentIndex(i);
break;
}
}
}
As you can see here, i am using an undocumented method (constData or data) on the QVariant (But well…. Isn't header's publicly exposed data the best documentation?). i have to do that because when trying QVariant::toInt() to compare data, the conversion fails each time… Why? Couldn't i teach QVariant to compare my custom enum types to each others?
As a subsidiary question: In the first snippet of code i show you, there is a QDebug line… It gives me:
QVariant(RE::E::ReadingDirection, )
QVariant(RE::E::ReadingDirection, )
QVariant(RE::E::ReadingDirection, )
QVariant(RE::E::ReadingDirection, )
QVariant(RE::E::ReadingDirection, )
For an enum having normally 5 different possible values… As you can see, the type is displayed correctly, but never the value.
What am i doing wrong here please?
Thanks a lot for all your expertise!
Pierre.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110808/2839f83c/attachment.html
More information about the Qt-interest-old
mailing list