QtのQFlags及び関連マクロ学習のまとめ
11744 ワード
http://blog.csdn.net/dbzhang800/article/details/6734273
起源
私達の5軸テーブルのために制御インターフェースを定義します.は、まず、エンムタイプを定義する.5つのエニュメレーション値は、それぞれの軸 を表す.インターフェースクラスを定義する 、ある絶対位置moveA に移動します.は相対量moveR を移動する.ゼロ操作doHome
doHomeに対しては、どの軸の動きをコントロールする必要がありますか?一つのQListで十分ですが、なんだかよくないです.となりました
QFlags
一度しか見たことがないですが、ずっと見たことがありません.
今になって、Manualをひっくり返して、ソースコードをねらってみました.えっと、もともとQFlagsはこんなに簡単なものです.
簡単に次のコードを書きます.
タイプ定義(typedef)とオペレータのリロードは、マクロQudeCLAREuFLAGSである.
注:この二つのマクロはQtのメタオブジェクトシステムとは関係がありません.
QuFLAGSとQuENUMS
前の2つのマクロと違って、この2つはmocによって処理されるマクロです.C++プリプロセッサにとっては、ただのスペースです.
元の対象の情報と関係がある以上、先にQMetaObjectのManualをねらうつもりです.意外にも!QFlagsの影がなくて、ただ QMetaEnum QMetaObject:enumerator(int index)const int QMetaObject:enumeratoCount()const int QMetaObject:enumerator Offset()const int QMetaObject:indexOfEnumerator(const char*name)const これらのもの
QuFLAGSのマンツールを詳しく見ています.
Note:This macro Taes care of register ing individual flags values with the meta-object system,so it is unnecessary to use QuENUMS()in addition to this macro.何を言いましたか?QuFLAGSを使ったと教えてくれます.QuENUMSを使う必要がありません.
どういうことですか
例を書いてテストしてみます.は、QuFLAGS(QuENUMSを用いず)のみを使用して、メタオブジェクト情報を登録する .は次に、メタオブジェクト内の列挙量情報 を出力する.
また何を見ますか?
mocで生成されたファイルを参照してください.
QuENUMSとQuFLAGSが同時に使用されると、確かに二つのQMetaEnumオブジェクトが生成される.
急に分かりました.なぜマンツールの中にいますか?
もともと、無意識のうちに、WindowTypeのエニュメレーション値はWidget/Windowのようなシングル値であり、DialogはWindowFlagsに属しています.
最初の例に戻ると、私が一番よく使うのはX、Y、Rの三つの軸です.そこで、エンムをこう定義します.
めちゃくちゃです.ここにメモしておきます.
起源
私達の5軸テーブルのために制御インターフェースを定義します.
enum AxisId {
Axis_X,
Axis_Y,
Axis_Z,
Axis_R,
Axis_T
};
class StageControl:public QObject
{
Q_OBJECT
public:
StageControl();
public slots:
void moveA(const QMap<AxisId, double> &);
void moveR(const QMap<AxisId, double> &);
void doHome(const QList<AxisId>&);
...
二つの移動操作は何も言うことはないはずです.命令はいつも含まれています.どの軸がどこに移動しますか?doHomeに対しては、どの軸の動きをコントロールする必要がありますか?一つのQListで十分ですが、なんだかよくないです.となりました
enum AxisId{
Axis_X = 0x01,
Axis_Y = 0x02,
Axis_Z = 0x04,
Axis_R = 0x08,
Axis_T = 0x10
};
class StageControl:public QObject
{
...
void doHome(int axes);
これでいいです. doHome(Axis| Axis Y) しかし、パラメータはintです.どうやって安全ではないですか?もし適当に整数を伝えたらどうすればいいですか?QFlags
一度しか見たことがないですが、ずっと見たことがありません.
今になって、Manualをひっくり返して、ソースコードをねらってみました.えっと、もともとQFlagsはこんなに簡単なものです.
簡単に次のコードを書きます.
typedef QFlags<AxisId> AxisIds;
StageControl:public QObject
{
...
void doHome(AxisIds axes);
しかし、これは仕事ができません.doHomeは最適なマッチング関数を見つけられません.全体を定義する必要があります.AxisIds operator|(AxisId, AxisId);
関数タイプ定義(typedef)とオペレータのリロードは、マクロQudeCLAREuFLAGSである.
Q_DECLARE_FLAGS(AxisIds, AxisId)
和宏QuDECLAREUOPAERATORSQ_DECLARE_OPERATORS_FOR_FLAGS(AxisIds)
やったこと注:この二つのマクロはQtのメタオブジェクトシステムとは関係がありません.
QuFLAGSとQuENUMS
前の2つのマクロと違って、この2つはmocによって処理されるマクロです.C++プリプロセッサにとっては、ただのスペースです.
元の対象の情報と関係がある以上、先にQMetaObjectのManualをねらうつもりです.意外にも!QFlagsの影がなくて、ただ
QuFLAGSのマンツールを詳しく見ています.
Note:This macro Taes care of register ing individual flags values with the meta-object system,so it is unnecessary to use QuENUMS()in addition to this macro.何を言いましたか?QuFLAGSを使ったと教えてくれます.QuENUMSを使う必要がありません.
どういうことですか
例を書いてテストしてみます.
class StageControl:public QObject
{
Q_OBJECT
public:
enum AxisId{
Axis_X = 0x01,
Axis_Y = 0x02,
Axis_Z = 0x04,
Axis_R = 0x08,
Axis_T = 0x10
};
//Q_ENUMS(AxisId)
Q_DECLARE_FLAGS(AxisIds, AxisId)
Q_FLAGS(AxisIds)
StageControl()
{
const QMetaObject * mobj = metaObject();
for (int i=mobj->enumeratorOffset(); i<mobj->enumeratorCount(); ++i) {
QMetaEnum menum = mobj->enumerator(i);
qDebug()<<"name: "<<menum.name();
for (int ii=0; ii<menum.keyCount(); ++ii) {
qDebug()<<menum.key(ii);
}
}
}
};
結果は以下の通りですname: AxisIds
Axis_X
Axis_Y
Axis_Z
Axis_R
Axis_T
ちょっと面白いです.QuENUMSだけを使った時の結果を比較してみます.name: AxisId
Axis_X
Axis_Y
Axis_Z
Axis_R
Axis_T
ふふ、二つは全部使いますか?name: AxisId
Axis_X
Axis_Y
Axis_Z
Axis_R
Axis_T
name: AxisIds
Axis_X
Axis_Y
Axis_Z
Axis_R
Axis_T
元対象システムに相当する二つのQMetaEnumオブジェクトがあります.また何を見ますか?
mocで生成されたファイルを参照してください.
QuENUMSとQuFLAGSが同時に使用されると、確かに二つのQMetaEnumオブジェクトが生成される.
static const uint qt_meta_data_StageControl[] = {
// content:
6, // revision
0, // classname
0, 0, // classinfo
0, 0, // methods
0, 0, // properties
2, 14, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// enums: name, flags, count, data
13, 0x0, 5, 22,
20, 0x1, 5, 32,
// enum data: key, value
28, uint(StageControl::Axis_X),
35, uint(StageControl::Axis_Y),
42, uint(StageControl::Axis_Z),
49, uint(StageControl::Axis_R),
56, uint(StageControl::Axis_T),
28, uint(StageControl::Axis_X),
35, uint(StageControl::Axis_Y),
42, uint(StageControl::Axis_Z),
49, uint(StageControl::Axis_R),
56, uint(StageControl::Axis_T),
0 // eod
};
static const char qt_meta_stringdata_StageControl[] = {
"StageControl\0AxisId\0AxisIds\0Axis_X\0"
"Axis_Y\0Axis_Z\0Axis_R\0Axis_T\0"
};
その他急に分かりました.なぜマンツールの中にいますか?
enum Qt::WindowType
flags Qt::WindowFlags
またはenum Qt::WindowState
flags Qt::WindowStates
いつもペアで紹介します!もともと、無意識のうちに、WindowTypeのエニュメレーション値はWidget/Windowのようなシングル値であり、DialogはWindowFlagsに属しています.
enum WindowType {
Widget = 0x00000000,
Window = 0x00000001,
Dialog = 0x00000002 | Window,
Sheet = 0x00000004 | Window,
Drawer = 0x00000006 | Window,
Popup = 0x00000008 | Window,
Tool = 0x0000000a | Window,
...
}
Q_DECLARE_FLAGS(WindowFlags, WindowType)
もともとこのような違いはありませんでした.最初の例に戻ると、私が一番よく使うのはX、Y、Rの三つの軸です.そこで、エンムをこう定義します.
enum AxisId{
Axis_X = 0x01,
Axis_Y = 0x02,
Axis_Z = 0x04,
Axis_R = 0x08,
Axis_T = 0x10,
Axis_2D = Axis_X|Axis_Y|Axis_R
};
後記めちゃくちゃです.ここにメモしておきます.