枚舉在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。
最後更新:2017-04-02 06:51:51