1.q_object
#defineQ_object Public: Q_object_checkStatic ConstQmetaobject Staticmetaobject; Virtual ConstQmetaobject *metaobject ()Const; Virtual void*qt_metacast (Const Char*); Qt_tr_functionsVirtual intQt_metacall (Qmetaobject::call,int,void**); Private: Q_decl_hidden_static_metacallStatic voidQt_static_metacall (Qobject *, Qmetaobject::call,int,void**); structqprivatesignal {};
When you define a macro O_object in a header file, we can use the signal and slot function just because it generates an MOC file
Qt_tr_functions This macro is also defined here. In other words, if you want to use TR () internationalization, you must use the Q_object macro, otherwise there is no TR () function. The most important thing in this period is virtual Const Qmetaobject *metaobject () const; Function. This function returns an instance of the Qmetaobject meta-object class, through which you gain the ability to reflect the Qt class: Get the type of this object, and all of this does not require the C + + compiler's RTTI support. Qt also provides a function qobject_case () similar to C + + dynamic_cast (), and the implementation of this function does not need to be RTTI. In addition, a class that does not have a Q_object macro defined is the same type as the closest parent class. That is, if a inherits Qobject and defines Q_object,b inherits a but does not define Q_OBJECT,C inherits B, then C's Qmetaobject::classname () function will return a, not its own name. Therefore, to avoid this problem, all classes that inherit the Qobject should define Q_object macros, whether you are using a signal slot or not.
Staticmetaobject and MetaObject They are all declared in the Qobject macro
Realize:
Const Qmetaobject Mainwindow::staticmetaobject = { &Qmainwindow::staticmetaobject, Qt_meta_ Stringdata_mainwindow.data, Qt_meta_data_mainwindow, qt_static_metacall, Q_nullptr, Q_NULLPTR}}; Const Const { return qobject::d _ptr->metaobject? Qobject::d _ptr->dynamicmetaobject (): &Staticmetaobject;}
Qobject::d _ptr->metaobject is only used for dynamic meta objects (QML objects), usually virtual functions metaobject () simply return the staticmetaobject of the class.
Staticmetaobject is created as read-only data. The definition of qmetaobject in the Qobjectdefs.h file is as follows:
structqmetaobject{/* ... skiped all the public functions ...*/ enumCall {Invokemetamethod, ReadProperty, WriteProperty,/*...*/ }; struct{//Private Data ConstQmetaobject *SuperData; ConstQbytearraydata *StringData; Const UINT*data; typedefvoid(*staticmetacallfunction) (Qobject *, Qmetaobject::call,int,void**); Staticmetacallfunction Static_metacall; ConstQmetaobject * *relatedmetaobjects; void*extradata;//reserved for future use} D;};
2.Q_D macro
Qt source has a lot of Q_Q and Q_d macros, where the use of these macros will always see a q pointer and D pointer, check the KDE documentation, generally understand the mechanism, Europe also! These private data access strategies for QT are well worth learning. Here's a brief summary.
D-pointer
The shared D pointer implementation is as follows:
1. Define a d_ptr pointer to the protected permission in the base class; 3 _2 K6 W5 v2 L1}
2, define D_FUNC () in each derived class, get the base class D_ptr, and convert it to the current private class pointer (derived from the base class D_ptr); 6 @: r/a/{% q
3, use Q_d in the function, so you can use D;. G3 h) _! M9 C1 I7 V) e ' t ' t
4, in the private data inheritance system, do not forget to define the destructor as virtual function, the base class destructor release d_ptr, in case of memory leaks!!! "| F2 N% X7 J5 Z3 N
5, the derivation of the class, plus the protected constructor, call the parent class constructor, the private data class to pass parameters;
Private Data declaration in the main class, q_d use, Y5 t-i) L5 K2 W
#define Q_DECLARE_PRIVATE (Class) \
Inline class# #Private * D_func () {return reinterpret_cast<class# #Private *> (Qgetptrhelper (D_ptr));} \
inline Const class# #Private * D_FUNC () const {return reinterpret_cast<const class# #Private *> (Qgetptrhelper (d_ptr )); } \ $ O6 v T9 F0 C # A
Friend class class# #Private; 3]3 J5 Q5 [2 A + @) V7 K8 Z
, s# B3 c& N; y {3 V;} * S6 Q
The private Data declaration in the main class (used when the D pointer is named non-d_ptr instead of dptr), Q_d uses 5 N4 Q. i$ B1 d# M
#define Q_DECLARE_PRIVATE_D (Dptr, Class) \ 1 R $ A! O8 A "T \+ Z4 E
Inline class# #Private * D_func () {return reinterpret_cast<class# #Private *> (Dptr);} \ + r+ g+ I5 M; m) ' 8 m
inline Const class# #Private * D_FUNC () const {return reinterpret_cast<const class# #Private *> (Dptr);} \
Friend class class# #Private;
#define Q_D (Class) class# #Private * Const D = D_func ()
Q pointer
Figure out the D pointer, the Q pointer is much simpler, there is no ' Q ' and ' d ' where a bit like, is dripping! ' Q ' is a ' d '. The direction of the Q pointer is exactly the opposite of the D pointer, which is used in the private data class (the D pointer is used only in the main class, that is, the class that uses the private data class, which is really a mouthful!). ) to get the main class pointer.
//Public data declaration in private class, Q_Q use % D9 i "M:u7 [$ @
#define Q_declare_public (Class) & nbsp; \ t$ C $ G3 M! I3 \8 X
inline class* Q_func () {return static_cast<class *> (q_ptr);} \
Inline const class* Q_func () const {return static_cast<const Class *> (q_ptr);} \
friend class class;
#define Q_Q (Class) class * Const Q = Q_func ()
/T9 E. @! P: o+ v* B
This mechanism of feeling QT destroys Oo, and I think that's why it only does internal use ... is a bit totally dependent on the flavor of the macro, unlike its signal/slot, which is compiled by MOC to insert metadata. However, it is convenient to hack. As for Signal/slot, I think it should be possible to use macro and function pointers as alternatives, and see again sometime. Here just to see about the D pointer to the article and your own experience simple summary translation, more detailed can see the following two connections.
QT key macro transfer from network finishing