Russian Qt Forum
Ноябрь 23, 2024, 16:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Qt и флаги  (Прочитано 14850 раз)
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« : Апрель 01, 2010, 22:09 »

Каким образом в Qt реализованы флаги (напр. Qt::QueuedConnection) и доступ к ним? Накидал:
Код
enum enType
{
flag1,
flag2
};
 
namespace Qt
{
enType str; //тут неправильно
}
 
Флаги это, по-идее, элементы enum. Но как к ним добраться через оператор разрешения ("::")?
Записан

kubuntu/Win7/x64/NetBeans
BRE
Гость
« Ответ #1 : Апрель 01, 2010, 22:15 »

Код
namespace Qt
{
enum enType
{
flag1,
flag2
};
 
}
 
int val = Qt::flag1;
 
Записан
SABROG
Гость
« Ответ #2 : Апрель 01, 2010, 22:22 »

Вообще сама область видимости Qt очень интересно сделана. С точки зрения экспорта из библиотек Qt это класс, а с точки зрения подключения в качестве хедера это обычный namespace. Вот бы найти QMetaObject класса Qt, тогда я бы мог для большинства флагов получать текстовые названия энумов для вывода отладки. Только где ж взять указатель на экземпляр класса Qt, если такой существует...

QMetaObject точно существует для Qt: moc_qnamespace.cpp
« Последнее редактирование: Апрель 01, 2010, 22:26 от SABROG » Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #3 : Апрель 01, 2010, 22:33 »

Да, меня подобная тематика тоже изначально заинтересовала. Спасиб за ответ.
Записан

kubuntu/Win7/x64/NetBeans
niXman
Гость
« Ответ #4 : Апрель 01, 2010, 22:55 »

так же, перечисления могут быть анонимными:
Код
C++ (Qt)
namespace qt {
   enum {
       one,
       two
   };
};
...
int v = qt::one;
 
в с++, по умолчанию, перечисления являются целыми(int)
но если перечисление, декларировано как в примере выше, то мы не сможем его использовать как тип:

Код
C++ (Qt)
void func(qt v) { // так нельзя. потому что qt, не является типом. это нэймспейс.
}
 

и по поводу нэймспейсов: они могут быть анонимные. для чего? - для того чтоб ограничить область видимости одним файлом. иногда просто необходимо. можно конечно придумать уникальное имя для этого нэймспейса, которое небудет перекрываться ни с одним другим. но, нужно обладать не шуточной фантазией, чтоб придумать 100 уникальных имен Подмигивающий
пример file1.h :
Код
C++ (Qt)
namespace {
  const std::string str = "blablabla";
};
 
// in the body of any function
std::string str1 = "oops..." + str;
 
но если file1.h подключить в file2.h, то переменной str, в нем существовать не будет.
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #5 : Апрель 01, 2010, 22:58 »

полезно!
Записан

kubuntu/Win7/x64/NetBeans
SABROG
Гость
« Ответ #6 : Апрель 01, 2010, 23:57 »

Да, меня подобная тематика тоже изначально заинтересовала. Спасиб за ответ.

Готово. Удалось таки сделать то, что было в голове около года.
Записан
niXman
Гость
« Ответ #7 : Апрель 02, 2010, 00:06 »

супер!
только сегодня об это думал)
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Апрель 02, 2010, 07:17 »

А я думал, что всё гораздо проще и уже собирался делать так как в QIODevice сделано, т.е. писать что-то вроде:
Код:
...
    enum OpenModeFlag {
        NotOpen = 0x0000,
        ReadOnly = 0x0001,
        WriteOnly = 0x0002,
        ReadWrite = ReadOnly | WriteOnly,
        Append = 0x0004,
        Truncate = 0x0008,
        Text = 0x0010,
        Unbuffered = 0x0020
    };
    Q_DECLARE_FLAGS(OpenMode, OpenModeFlag)
...

Думал - что это и есть решение проблемы! А оказывается  - всё не так?
Записан

ArchLinux x86_64 / Win10 64 bit
SimpleSunny
Гость
« Ответ #9 : Апрель 02, 2010, 08:07 »

OFFTOPIC
Блин, и не знал про SecretsOfQtFull.pdf, может кто-нить выложит? Так как весь http://labs.trolltech.com/page/Projects/DevDays/DevDays2007 недоступен почему-то, а интересно что там внутри Улыбающийся
Записан
SABROG
Гость
« Ответ #10 : Апрель 02, 2010, 08:24 »

OFFTOPIC
Блин, и не знал про SecretsOfQtFull.pdf, может кто-нить выложит? Так как весь http://labs.trolltech.com/page/Projects/DevDays/DevDays2007 недоступен почему-то, а интересно что там внутри Улыбающийся

Выложил все архивы, давно как-то скачивал.

Цитировать
Думал - что это и есть решение проблемы! А оказывается  - всё не так?
Дублировать перечисления Qt в то время как они статические, а значит общие для всех классов QObject'a? Вариант конечно, но скорее для безвыходной ситуации, если тролли что-то поменяют и метод перестанет работать.
« Последнее редактирование: Апрель 02, 2010, 08:38 от SABROG » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #11 : Апрель 02, 2010, 09:43 »

Цитировать
Дублировать перечисления Qt в то время как они статические, а значит общие для всех классов QObject'a? Вариант конечно, но скорее для безвыходной ситуации, если тролли что-то поменяют и метод перестанет работать.

Ненене.. Я другое имел ввиду.

К примеру создаю свой класс и в нём объявляю енумы:

MyClass.h
Код:
...
    enum MyModeFlag {
        MyFlag1,
        MyFlag2,
        ....
        MyFlagN
    };
...

а потом сделать:
Код:
...
    Q_DECLARE_FLAGS(MyMode, MyModeFlag)
...

т.е. я думал, что этот "волшебный" макрос Q_DECLARE_FLAGS - сам всё там делает, т.е. при компиляции , moc или нечто иное, парсит MyClass.h ищет задекларированные флаги этим макросом и присваивает им "текстовые" имена.. т.е парсит слова MyFlag1, MyFlag2 и т.п. и внутрях у себя уже создает нужные привязки.. или как то так Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
SABROG
Гость
« Ответ #12 : Апрель 02, 2010, 13:18 »

т.е. я думал, что этот "волшебный" макрос Q_DECLARE_FLAGS - сам всё там делает, т.е. при компиляции ,

Правильно думал, только флаги и перечисления немного разные вещи. Например для обычных перечислений нужно использовать макрос Q_ENUMS(), для флагов на основе перечислений Q_DECLARE_FLAGS. Но это всё решения, которые предназначены для пользовательских типов. Я сейчас говорю о готовых перечислениях внутри Qt.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #13 : Апрель 02, 2010, 13:33 »

Цитировать
Правильно думал, только флаги и перечисления немного разные вещи. Например для обычных перечислений нужно использовать макрос Q_ENUMS(), для флагов на основе перечислений Q_DECLARE_FLAGS. Но это всё решения, которые предназначены для пользовательских типов. Я сейчас говорю о готовых перечислениях внутри Qt.

хм.. что-то не выходит...

вот коды:
MyClass.h
Код:

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass(QObject *parent = 0);

        enum MyModeFlag {
        Mode1 = 0,
        Mode2 = 1,
        Mode3 = 2
    };
    Q_DECLARE_FLAGS(MyMode, MyModeFlag)

    void setMode(MyClass::MyMode m);
    MyClass::MyMode getMode() const;

private:
    MyClass::MyMode m_mode;
};

MyClass.cpp
Код:
MyClass::MyClass(QObject *parent)
        : QObject(parent), m_mode(MyClass::Mode1)
{
}

void MyClass::setMode(MyClass::MyMode m)
{
    m_mode = m;
}

MyClass::MyMode MyClass::getMode() const
{
    return m_mode;
}


main.cpp
Код:
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyClass mc;

    qDebug() << "Default mode: " << mc.getMode();

    mc.setMode(MyClass::Mode3);

    qDebug() << "New mode: " << mc.getMode();

    return a.exec();
}

при запуске выводит:
Цитировать
...
Default mode:  0
New mode:  2
...

а нужно что бы было типа:
Цитировать
...
Default mode:  MyMode( "MyFlag1" )
New mode:  MyMode( "MyFlag3" )
...

что нужно подправить? Улыбающийся

Прикрепляю проект
« Последнее редактирование: Апрель 02, 2010, 13:58 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
SABROG
Гость
« Ответ #14 : Апрель 02, 2010, 14:08 »

Цитировать
что нужно подправить?

Много чего. Вот пример:

Код
C++ (Qt)
#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QMetaObject>
#include <QtCore/QMetaEnum>
 
class Programmer : public QObject
{
   Q_OBJECT
public:
   enum Language {ASM, C, CPP, PASCAL, FORTRAN, BASIC, JAVA};
   Q_ENUMS(Language)
};
 
int main(int argc, char *argv[])
{
   const QMetaObject &mo = Programmer::staticMetaObject;
   int index = mo.indexOfEnumerator("Language");
   QMetaEnum me = mo.enumerator(index);
 
   Programmer::Language p = Programmer::CPP;
   Programmer::Language l= static_cast<Programmer::Language>(me.keyToValue("CPP"));
 
   qDebug() << me.valueToKey(p) << ":" << l;
   return 0;
}
 
#include "main.moc"
 
 
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.119 секунд. Запросов: 25.