PDA

View Full Version : Comparing a Qstring with a value defined in an enum



AndresBarbaRoja
24th March 2011, 10:16
Hi, I am recieving a string that defines the function i have to call. To do this I wrote this class:


class MiTableClass:public QObject
{
Q_OBJECT
Q_ENUMS(MiTableElements);

//This is a singleton class but i deleted the extra code lines for this post.

public:
int indexOf(QString);
QString commandNumber(int);

enum MiTableElements
{
//Eth commands
AUTOTEST,//0
HALT,//1
STANDBY,//2
SSNORMAL,//3
};//The enum is way longer
};

int MiTableClass::indexOf(QString command)
{
const QMetaObject metaObject=m_Instance->staticMetaObject;
int index = metaObject.indexOfEnumerator("MiTableElements");
QMetaEnum metaEnum = metaObject.enumerator(index);
int i=metaEnum.keyToValue(command.toLatin1());
return i;
}

QString MiTableClass::commandNumber(int nCmd)
{
const QMetaObject metaObject=m_Instance->staticMetaObject;
int index = metaObject.indexOfEnumerator("MiTableElements");
QMetaEnum metaEnum = metaObject.enumerator(index);
QString str=metaEnum.valueToKey(nCmd);
return str;
}


and the to use it I do this


void HLP_MessageProcessor::run()
{
MiTableClass * mi =MiTableClass::Instance();
lst=message.split(",");

//Figuring out the command code
int i=mi->indexOf(lst[0]);
switch(i)
{
case 0://AUTOTEST
AUTOTEST_Function();
break;
case 1://HALT
HALT_Function();
//The lack of break here is on purpouse
case 2://STANDBY
STANDBY_Function();
}
}

Now the thing is that I will have to add cases inbetween the ones i already have and I would like to be able to write

switch(i)
{
case AUTOTEST:
...

And i do not know where to declare the enum so I can use it in this way for the switch.

So far i tried to put it as a global enum, but then the class members that compare the string with the enum value stopped to work.
Any ideas?
How to register the global enum inside my class? i'm lost in this topic

stampede
24th March 2011, 10:19
enum is a public member of MiTableClass, so this will work:

switch(i)
{
case MiTableClass::AUTOTEST:
...

wysota
24th March 2011, 11:07
Furthermore if you declare AUTOTEST_Function() (and all the others) as Q_INVOKABLE (or as slots) you can do:

void HLP_MessageProcessor::run()
{
MiTableClass * mi =MiTableClass::Instance();
lst=message.split(",");
QMetaObject::invokeMethod(qPrintable(QString("%1_Function").arg(lst[0])));
}

AndresBarbaRoja
24th March 2011, 12:31
Thanks, to both of you. Right now stampede sugestion works fine. And i'll start declaring slots because i like the way the wysota code looks :D

AndresBarbaRoja
24th March 2011, 15:13
Just an observation in case someone else reads this.
The invokeMethod requires the object from which you want to execute the member, so i added "this" to my code so it would compile:


void HLP_MessageProcessor::run()
{
MiTableClass * mi =MiTableClass::Instance();
lst=message.split(",");
QMetaObject::invokeMethod(qPrintable(this,QString("%1_Function").arg(lst[0])));
}

In any case, I declared all functions as private slots, the invokeMethod seems to be calling them (it returns true) but the debugger never stops in the breakpoint inside the called function. Any ideas why?

wysota
24th March 2011, 16:11
This works fine for me:

#include <QtCore>

class Caller : public QObject {
Q_OBJECT
public:
Caller(){}

protected:
Q_INVOKABLE void func1() {
qDebug() << Q_FUNC_INFO;
}

Q_INVOKABLE void func2() {
qDebug() << Q_FUNC_INFO;
}
};

#include "main.moc"

int main(int argc, char **argv){
Caller c;
QMetaObject::invokeMethod(&c, argv[1]);
return 0;
}

Called as:

$ ./invokable func1
void Caller::func1()
$ ./invokable falafel
QMetaObject::invokeMethod: No such method Caller::falafel()