枚举在QML的使用

           在上一篇关于QML的博客《QML与指针》中讲到了在QML中如果要使用C++的类或者其他类型都必须要注册。其中注册方式之一就是使用qmlRegisterType<T>()。只要不是内建类型比如:int, QString, bool, QPoint等等,其他的类型如果要在QML中使用,都必须向QML注册,但是注册类型必须有个要求:被注册的类型都必须间接或者直接以QObject为父类。这一点就要求了枚举类型必须声明在Qt类的内部。懂C++的人都知道,将枚举声明在类的内部,在其他类中使用该枚举类型的时候,必须使用该类来引用例如:class A内部声明了一个枚举类型DataType,那么如果要在其他类中使用改枚举类型,就必须使用A::DataType这种方式。如果把枚举类型和自己写的有特定业务的class混在一起,在其他类中使用的时候会造成很多麻烦

        基于这一点考虑,我们可以模仿Qt的命名空间的思想。给自己需要在QML中使用的枚举等其他类型放到一个专门的命名空间中。这样避免了类与类之间的混淆。另外,向QML注册枚举类型注册方式跟注册类不一样,注册枚举类型需要使用Q_ENUMS()来注册。先来看看代码:

#include <QObject>

class HarlenTan: public QObject {
    
    Q_OBJECT
    Q_ENUMS(DataType)
    Q_ENUMS(RequestType)
    
public:
    
    enum DataType {
        Type1,
        Type2,
        Type3
    };
    
    enum RequestType {
        Network,
        Comport,
        Filetrans
    };
    
};

这样,注意,上面枚举类里面的数据都是大写字母开头,在QML中,必须以大写字母开头才能表示类型,同样,枚举也不例外,所以里面的必须以大写字母开头QML才能认识。这样,在QML中,需要使用枚举的地方都可以使用 HarlenTan.Type1的方式来使用。比如你可以给QML中某个变量赋予HarlenTan.Type2.

       上面讲到了如何注册枚举,如何给变量赋予枚举。那么很自然,我经常会有这种需求,就是在QML中调用c++函数,函数的参数就是我们注册的枚举类型比如RequestType.

函数签名如下:

void  operation(RequestType tpye);

这样,我们是不是可以在QML中通过已经注册的对象或者类直接调用该函数,并给他传入枚举类型就可以了呢?方式如下:

//qml file

objId.operation(HarlenTan.Network)
答案是:不可以。我们类分析这个过程。首先是定义了一个局部变量 RequestType type,然后将HarlenTan.Network这个枚举赋值给这个局部变量。但是,我们又知道,凡是在QML中直接操作的成员变量都必须是通过Q_PROPERTY()方式注册过的才能使用。例如:


Q_PROPERTY(HarlenTan::RequestType reqType READ GetType WRITE SetType)
//其中,GetType和SetType需要自己实现,然后系统会自动调用

但是问题是,我们没办法为局部变量提供这种注册,这种注册至少也要是QObject的子类中的成员变量。所以,这种方式行不通。不过我们可以绕道,既然传值行不通。我们可以先给成员变量赋值,然后在函数类去获取成员的值。

意思即是说先通过  定义一个成员变量,然后注册该成员变量,然后在QML中使用 m_reqType = HarlenTan.Network传值给成员变量。然后在operation函数内部区读取m_reqType这个成员变量就可以达到目的了。


其实,在QML内部,实质就是将枚举当做int来看待。当然,仅限于在QML当中。我们可以定 property int a: HarlenTan.Network。

上一篇:在Windows 2003下使用QuickCam


下一篇:ubuntu16.04 使用adb连接Android手机及——python实现看小说自动翻页