Qt World Summit: Register Today!

[Solved] Enum in C++ class can't be managed as explained in the Qt Property System

  • Hi,

    I have a very strange problem. I receive an error that I have no idea what it happens. The scenario is the following (very simple)

    There is a class WebQuery managind several web service generic calls. There I need to work with QML using a couple of settings based on enums. To do this, I followed the document "The property system" from the Qt documentation (working with 4.7.4 / Qt Creator 2.3.0)
    The essential code elements are the following:
    /////////// the webquery.h file /////////////
    class WebQuery : public QObject
    // various properties ...
    // Then the destination and savemode properties defined as follows
    Q_PROPERTY(Destination destination READ destination WRITE setDestination)
    Q_PROPERTY(SaveMode savemode READ savemode WRITE setSavemode)
    // ... and the QENUMS macro for the two enum types.
    Q_ENUMS(Destination SaveMode)

    // These are the two enums
    enum Destination { Tmp, AppDir, HomeDir, WorkDir };
    enum SaveMode { Overwrite, NoOverwrite, Uncompress, UncompressOverwrite, DataOnly, DeleteAnyway };

    explicit WebQuery(QObject *parent = 0);
    virtual ~WebQuery();
    // Here are the prototypes of the funcitons
    Destination destination() const;
    void setDestination(const Destination);
    SaveMode savemode() const;
    void setSavemode(const SaveMode);

    Every element here seems correct and the editro show me all the objects, types etc with the right syntax-coloring, the definition etc. Included the enums and their funcions.

    In the source code webquery.cpp instead toegether with the class stuff I define the functions in the following way:
    include "webquery.h"

    [ ... class stuff ...]

    SaveMode WebQuery::savemode() const
    { return m_savemode; }

    void WebQuery::setSavemode(const SaveMode sm)
    { m_savemode = sm; }

    Destination WebQuery::destination() const
    { return m_destination; }

    void WebQuery::setDestination(const Destination ds)
    { m_destination = ds; }
    Only in destination() and savemode() the types of the functions (respectively Destination and SaveMode accepted as correct in the include file) are shown as unknown.
    When I try to compile I receive two errors for these two functions: Destination does not name a type and SaveMode does not name a type.
    Regardless by the Qt this is C++ syntax it seems.

    Some idea? I have done something wrong but I can't see the error?

    Thank you again.

  • Use macro Q_ENUMS twice in webquery.h:
    And syntax with WebQuery:: in webquery.cpp:
    WebQuery::SaveMode WebQuery::savemode() const
    { return m_savemode; }
    WebQuery::Destination WebQuery::destination() const
    { return m_destination; }

  • @Konstantin: thank you for the suggestios. Many thanks, this works :)

    Now the question is why this changes?

    in webquery.cpp I include webquery.h first else it is impossible to compile due that all the file inclusions are defined only in webquery.h Is this a special behavior of C++ the need to specify the local enum type with the class again as you indicate in WebQuery::EnumType WebQuery::function_name() ?

    In the "QObject class reference":http://developer.qt.nokia.com/doc/qt-4.7/qobject.html the doc explicitly says:

    bq. This macro registers one or several enum types to the meta-object system.

    I investigated about this statement because I was curious of the plural in Q_ENUMS macro. In some examples Q_ENUMS included more than one enum type and when I defines it in the code the syntax coloring of the editor accepted it as correct.
    Is it a bug of the macro ?

    Thank you again, you saved a lot of time!

  • Hi, I rechecked for QENUMS plural definition and it works also with my initial definition. The change that solves the problem is related to the changes in the funcitons in the webquery.cpp source code.

    I will be sure that it is a C++ correct syntax instead of a particularity of Qt source code.

  • Sorry. I bad speak English.

    I usually use for each enum Q_ENUMS separately. Now I know that it works for several enum. Thanks :-)

    Q_ENUMS macro is declared in the header file qobjectdefs.h

    define Q_ENUMS (x)

    preprocessed and converted into a void. Within this macro, you can write anything you want. The thing is how it will handle "moc":http://doc.qt.nokia.com/4.7/moc.html#moc and what code will create. This refers to the features Qt.

    As for the problem in webquest.cpp. Enum declared within the class is recognized in the implementation of its functions, but not a separate type of data outside of class. It is therefore necessary to apply the dereference.

  • [quote author="Konstantin Podsvirov" date="1316077615"]As for the problem in webquest.cpp. Enum declared within the class is recognized in the implementation of its functions, but not a separate type of data outside of class. It is therefore necessary to apply the dereference.

    Konstantin, I am aware of what you write and this is just the question: the .cpp file is the implementation of the same class whose enum and prototypes are defined in the .h file. Enum and any type (including struct and struct type) defined in a class should be recognized by the class itself. The strange is that in the .h the funciton prototype is accepted - as I expect - and the same function implementation in the code will not. It is an incoherence...

    In the meanwhile I searched if there was some kind of exception for this case in C++ but I have found nothing on the net. What do you think about ?

  • My programming experience in c + + suggests that no. There are no exceptions.
    I will point out that you are using and what does not cause you objections.
    To implement the function in webquery.cpp (outside the definition of webquiry.h) do you use dereferencing specifying the name of the class. On the enumeration defined within a class is the same. EnumName And ClassName::EnumName different things when viewed from the side (outside class). This is logical from the standpoint of the compiler, which must understand that we wrote.

  • Yep!

    As a matter of fact for a complete disambiguation I will use this way of define the enum in the include file outside of the class prototype definition.

    Thank you for the clarification. Anyway, you saved a lot of time.

Log in to reply