Qt metaobject sysmtem description 3: Implementation of the qmetaobject Interface

Source: Internet
Author: User
Document directory
  • Qmetaobject: classname ()
  • Qmetaobject: superclass ()
  • Qmetaobject: classinfocount ()
  • Qmetaobject: classinfooffset ()
  • Qmetaobject: classinfo (INT index)
  • Qmetaobject: indexofclassinfo ()
  • Int constructorcount () const
  • Qmetamethod Constructor (INT index) const
  • Int indexofconstructor (const char * constructor) const
  • Intindexofsignal (const char * signal) const
  • Qmetapropertyproperty (INT index) const
  • Qmetapropertyuserproperty () const

This article explains the implementation of related interfaces from the source code of QT metaobject. These interfaces are defined in qmetaobject. cpp.

Qmetaobject: classname ()

Inline const char * qmetaobject: classname () const

{Return D. stringdata ;}

 

From the previous article, we can see that D. stringdata is the string data that contains several C strings ending with '/0. If D. stringdata is treated as a C string pointer, it is the first string of the string sequence, and it is the class name.

Qmetaobject: superclass ()

Inline const qmetaobject * qmetaobject: superclass () const

{Return D. superdata ;}

 

Qmetaobject: classinfocount ()

Int qmetaobject: classinfocount () const

{

Int n = priv (D. Data)-> classinfocount;

Const qmetaobject * m = D. superdata;

While (m ){

N + = priv (m-> D. Data)-> classinfocount;

M = m-> D. superdata;

}

Return N;

}

 

From the code, we can see that the number of all classinfo returned for this class includes the number of all base classes.

 

The priv function is a simple inline function:

Static inline const qmetaobjectprivate * priv (const uint * Data)
{Return reinterpret_cast <const qmetaobjectprivate *> (data );}

According to the previous article, D. data points to the binary information. priv interprets D. Data as qmetaobjectprivate.

 

Qmetaobjectprivate is the private implementation class of qmetaobject. Its data definition is as follows (see the header file qmetaobject_p.h ). It corresponds to the content of the previous example MOC file, and its meaning is clear at a glance.
Struct qmetaobjectprivate
{
Int revision;
Int classname;
Int classinfocount, classinfodata;
Int methodcount, methoddata;
Int propertycount, propertydata;
Int enumeratorcount, enumeratordata;
Int constructorcount, constructordata; // Since Revision 2
Int flags; // Since Revision 3
Int signalcount; // Since Revision
}

Qmetaobject: classinfooffset ()

Int classinfooffset () const

{

Int offset = 0;
Const qmetaobject * m = D. superdata;
While (m ){
Offset + = priv (m-> D. Data)-> classinfocount;
M = m-> D. superdata;
}
Return offset;

}

The meaning of this class is to return the starting index value of the classinfo defined by this class, which is equivalent to the number of classinfo defined by its ancestor class.

 

Qmetaobject: classinfo (INT index)

Qmetaclassinfo classinfo (INT index) const

{

Int I = index;
I-= classinfooffset ();
If (I <0 & D. superdata)
Return D. superdata-> classinfo (INDEX );

Qmetaclassinfo result;
If (I> = 0 & I <priv (D. Data)-> classinfocount ){
Result. mobj = this;
Result. Handle = priv (D. Data)-> classinfodata + 2 * I;
}
Return result;

}

The process of this Code is relatively simple. Priv (D. data)-> classinfodata is the information of classinfo in D. data offset; each classinfo information occupies the size of two uint, so "priv (D. data)-> classinfodata + 2 * I "the value of this expression is the information of the I classinfo in D. offset in data.

Qmetaobject: indexofclassinfo ()

Int indexofclassinfo (const char * Name) const

{

Int I =-1;
Const qmetaobject * m = this;
While (M & I <0 ){
For (I = priv (m-> D. Data)-> classInfoCount-1; I> = 0; -- I)
If (strcmp (name, M-> D. stringdata
+ M-> D. Data [priv (m-> D. Data)-> classinfodata + 2 * I]) = 0 ){
I + = m-> classinfooffset ();
Break;
}
M = m-> D. superdata;
}
Return I;

}

 

Find the classinfo with the name from the bottom up according to the inheritance level.

Refer to the interpretation of the previous function. The expression m-> D. data [priv (m-> D. data)-> classinfodata + 2 * I] is the first 32-bit value of the I-th classinfo information. This value is the index value in character information block D. stringdata. Therefore, M-> D. stringdata +
M-> D. Data [priv (m-> D. Data)-> classinfodata + 2 * I] is the string of the classinfo name.

 

Int constructorcount () const

Int qmetaobject: constructorcount () const
{
If (priv (D. Data)-> revision <2)
Return 0;
Return priv (D. Data)-> constructorcount;
}

 

Qmetamethod Constructor (INT index) const

Qmetamethod qmetaobject: Constructor (INT index) const
{
Int I = index;
Qmetamethod result;
If (priv (D. Data)-> revision> = 2 & I> = 0 & I <priv (D. Data)-> constructorcount ){
Result. mobj = this;
Result. Handle = priv (D. Data)-> constructordata + 5 * I;
}
Return result;
}

 

Int indexofconstructor (const char * constructor) const

Int qmetaobject: indexofconstructor (const char * constructor) const
{
If (priv (D. Data)-> revision <2)
Return-1;
For (INT I = priv (D. Data)-> constructorCount-1; I> = 0; -- I ){
If (strcmp (constructor, D. stringdata
+ D. Data [priv (D. Data)-> constructordata + 5 * I]) = 0 ){
Return I;
}
}
Return-1;
}

 

Int enumeratorcount () const

Int enumeratoroffset () const

Qmetaenum enumerator (INT index) const

Int indexofenumerator (const char * Name) const

The implementation of this group of functions is similar to that of classinfo.

 

 

 


Intmethodcount () const;


Intmethodoffset () const;

Qmetamethodmethod (INT index) const

{

Int I = index;
I-= methodoffset ();
If (I <0 & D. superdata)
Return D. superdata-> method (INDEX );

Qmetamethod result;
If (I> = 0 & I <priv (D. Data)-> methodcount ){
Result. mobj = this;
Result. Handle = priv (D. Data)-> methoddata + 5 * I;
}
Return result;

}

The implementation method of this function is also clear at a glance.

 

Intindexofmethod (const char * method) const omitted;

Intindexofsignal (const char * signal) const

{

Const qmetaobject * m = this;
Int I = qmetaobjectprivate: indexofsignalrelative (& M, signal );
If (I> = 0)
I + = m-> methodoffset ();
Return I;

}

Int qmetaobjectprivate: indexofsignalrelative (const qmetaobject ** baseobject, const char * signal)
{
Int I =-1;
While (* baseobject ){
Const qmetaobject * const M = * baseobject;
For (I = priv (m-> D. Data)-> methodCount-1; I> = 0; -- I)
If (m-> D. Data [priv (m-> D. Data)-> methoddata + 5 * I + 4] & methodtypemask) = methodsignal
& Strcmp (signal, M-> D. stringdata
+ M-> D. Data [priv (m-> D. Data)-> methoddata + 5 * I]) = 0 ){
Break;
}
If (I> = 0)
Break;
* Baseobject = m-> D. superdata;
}

}

It can be seen that the special feature of searching for signal is that the fifth item of method metadata is used to determine whether this is a signal.

 

Intindexofslot (const char * slot) const omitted;

 

Intpropertycount () const;
Intpropertyoffset () const;

Intindexofproperty (const char * Name) const omitted;

Qmetapropertyproperty (INT index) const

{

Int I = index;
I-= propertyoffset ();
If (I <0 & D. superdata)
Return D. superdata-> property (INDEX );

Qmetaproperty result;
If (I> = 0 & I <priv (D. Data)-> propertycount ){
Int handle = priv (D. Data)-> propertydata + 3 * I;
Int flags = D. Data [Handle + 2];
Const char * type = D. stringdata + D. Data [Handle + 1];
Result. mobj = this;
Result. Handle = handle;
Result. idx = I;

If (flags & enumorflag ){
Result. menum = enumerator (indexofenumerator (type ));
If (! Result. menum. isvalid ()){
Qbytearray enum_name = type;
Qbytearray scope_name = D. stringdata;
Int S = enum_name.lastindexof ("::");
If (S> 0 ){
Scope_name = enum_name.left (s );
Enum_name = enum_name.mid (S + 2 );
}
Const qmetaobject * scope = 0;
If (scope_name = "QT ")
Scope = & qobject: staticqtmetaobject;
Else
Scope = qmetaobject_findmetaobject (this, scope_name );
If (Scope)
Result. menum = scope-> enumerator (scope-> indexofenumerator (enum_name ));
}
}
}
Return result;

}

The special feature of this function is that if this propery is an enumeration type, the correct qmetaenum attribute value is assigned to the returned value qmetapropery.

 

Qmetapropertyuserproperty () const

{

Const int propcount = propertycount ();
For (INT I = propcount-1; I> = 0; -- I ){
Const qmetaproperty prop = property (I );
If (prop. isuser ())
Return prop;
}
Return qmetaproperty ();

}

 

From the implementation of this function, a qobject should have only one property that opens the user flag.

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.