Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Sasha от Январь 16, 2014, 22:02



Название: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 16, 2014, 22:02
Здравствуйте,

Как применить макрос Q_ENUMS для перечислений из другого класса?

Судя по документации нужно просто указать имя перечисления вместе с имененм класса, но в следующем коде:
Код
C++ (Qt)
class A : public QObject
{
Q_OBJECT
...
enum eType{ Type1, Type2 };
...
};
class C: public QObject
{
Q_OBJECT
Q_ENUMS( A::eType )
void Test()
{
   const QMetaObject *pm = metaObject();
   QList<QString> lNamesEnums;
   QList< QList<QString> > lEnumsNames;
   for( int i=0, n=pm->enumeratorCount(); i<n; i++ )
   {
       QMetaEnum m = pm->enumerator(i);
       lNamesEnums += m.name();
       QList<QString> keys;
       for( int i=0,n=m.keyCount(); i<n; i++ )
            keys += m.key(i);
       lEnumsNames += keys;
   }
}
};
 
pm->enumeratorCount() оказывается = 0 Почему?


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: gil9red от Январь 16, 2014, 22:33
Может перечисление нужно сделать открытым? )
Код
C++ (Qt)
public:
enum eType{ Type1, Type2 };


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 17, 2014, 12:29
Может перечисление нужно сделать открытым? )
Код
C++ (Qt)
public:
enum eType{ Type1, Type2 };
Нет, оно и так открытое, просто я это не написал. Если оно закрытое, то код не компилируется, а так всё компилируется, но не работает


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Fregloin от Январь 17, 2014, 15:16
Для начала следует проверить, является ли данный тип энумератором или флагом.

Вот как реализовано у меня и все работает:

Код:
class RAILCORESHARED_EXPORT QRailItem : public QGraphicsObject, public CXMLSerializationInterface
{
    Q_OBJECT
private:

    Q_FLAGS(Qt::Alignment)
    Q_PROPERTY(Qt::Alignment    title_flags             READ    textFlags           WRITE   setTextFlags            DESIGNABLE  true    RESET   reset_title_flags)

};

Все работает как надо.


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 21, 2014, 11:11
Для начала следует проверить, является ли данный тип энумератором или флагом.

Вот как реализовано у меня и все работает:

Код:
class RAILCORESHARED_EXPORT QRailItem : public QGraphicsObject, public CXMLSerializationInterface
{
    Q_OBJECT
private:

    Q_FLAGS(Qt::Alignment)
    Q_PROPERTY(Qt::Alignment    title_flags             READ    textFlags           WRITE   setTextFlags            DESIGNABLE  true    RESET   reset_title_flags)

};

Все работает как надо.
Не совсем понятно, что именно "работает как надо". По-моему для создания Q_PROPERTY не обязательно объявлять Q_FLAGS. Мне интересно получится ли у Вас после добавления слова Q_FLAGS перечислить эти флаги так как это пытался я, когда описывал свою проблемму. К тому-же ещё до определения "является ли данный тип энумератором или флагом" я вызываю ф-ю enumeratorCount, которая должна вернуть сумарное количество и энумераторов и флагов. И вот она возвращает 0. Я попробовал, также добавить в свой класс Q_FLAGS(Qt::Alignment). Результат нулевой.


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: kambala от Январь 21, 2014, 12:04
Q_ENUMS надо ставить в класс А, а не в С, и мета-объект запрашивать у класса А через статический метод staticMetaObject()


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 21, 2014, 12:09
Q_ENUMS надо ставить в класс А, а не в С, и мета-объект запрашивать у класса А через статический метод staticMetaObject()
А что тогда означает строка в документации:
Цитировать
If you want to register an enum that is declared in another class, the enum must be fully qualified with the name of the class defining it. In addition, the class defining the enum has to inherit QObject as well as declare the enum using Q_ENUMS().


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Figaro от Январь 21, 2014, 12:40
Плохо с английским? Перевести?


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 21, 2014, 12:42
Плохо с английским? Перевести?
да


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Figaro от Январь 21, 2014, 12:52
Если вы хотите зарегистрировать ENUM объявленным в другом классе, ENUM должен быть полностью квалифицированным (подразумевается полностью указанный namespace и class со всеми вложенностями)  с именем класса в котором определен. В дополнении, класс определяющий ENUM должен быть наследован от QObject чтобы сработал макрос Q_ENUMS..

Эт немного литературный мой перевод... лень смотреть словари


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 21, 2014, 13:21
Если вы хотите зарегистрировать ENUM объявленным в другом классе, ENUM должен быть полностью квалифицированным (подразумевается полностью указанный namespace и class со всеми вложенностями)  с именем класса в котором определен. В дополнении, класс определяющий ENUM должен быть наследован от QObject чтобы сработал макрос Q_ENUMS..

Эт немного литературный мой перевод... лень смотреть словари
Примерно так понял и я. И вроде бы все необходимые вещи выполнил (и снаследовал от QObject оба класса). могу ещё раз код привести. Но всё равно enumeratorCount возвращает 0. Почему?


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: kambala от Январь 21, 2014, 14:15
насколько я понял из описания, надо чтобы класс А тоже регистрировал перечисление в Q_ENUMS, а не то, что написал Фигаро в конце (as well as переводится «так же как и»).

я с перечислениями обращаюсь так:
Код
C++ (Qt)
class ItemStorage
{
   Q_GADGET
   Q_ENUMS(ItemStorageEnum)
 
public:
   enum ItemStorageEnum
   {
       NotInStorage = 0,
       Inventory,
       Cube = 4,
       Stash,
       PersonalStash,
       SharedStash,
       HCStash
   };
 
   static QMetaEnum metaEnum() { return metaEnumFromName<ItemStorage>("ItemStorageEnum"); }
};


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Sasha от Январь 21, 2014, 14:58
насколько я понял из описания, надо чтобы класс А тоже регистрировал перечисление в Q_ENUMS, а не то, что написал Фигаро в конце (as well as переводится «так же как и»).
Если имеется ввиду, что для того, чтобы в классе C заработало Q_ENUMS(A::eType), нужно в классе A добавить Q_ENUMS( eType ), то я так тоже делал и бестолку.

Цитировать
я с перечислениями обращаюсь так:
Код
C++ (Qt)
class ItemStorage
{
   Q_GADGET
   Q_ENUMS(ItemStorageEnum)
 
public:
   enum ItemStorageEnum
   {
       NotInStorage = 0,
       Inventory,
       Cube = 4,
       Stash,
       PersonalStash,
       SharedStash,
       HCStash
   };
 
   static QMetaEnum metaEnum() { return metaEnumFromName<ItemStorage>("ItemStorageEnum"); }
};
насчёт этого надо подумать. Вообще, главная моя цель - это чтобы в скриптах можно было использовать перечисления по именам, но дело в том, что изначально перечисления у меня объявлены не в том классе, через который я хочу обращаться к ним из скриптов. Поэтому мне и нужно объявить Q_ENUMS( A::eType ). Но пока не получается


Название: Re: Q_ENUMS для перечислений из другого класса
Отправлено: Figaro от Январь 21, 2014, 15:08
Согласен с kambala на лету переводил...