Qt attribute system details

Source: Internet
Author: User

Qt provides a wonderful property system. Similar to the Attributes provided by the compiler. However, as a library independent of compilers and platforms, QT does not rely on non-standard compilation features, such as _ property or [property]. Qt can be compiled under any standard compiler on any platform. The QT property system is based on the metadata object system, which provides the built-in signal and slot communication mechanism of the object.

Declare attributes

To declare an attribute, you must use the q_property () macro in the class inherited from the qobject.
Q_property (type name
Read getfunction
[Write setfunction]
[Reset resetfunction]
[Policy policysignal]
[Designable bool]
[Scriptable bool]
[Stored bool]
[User bool]
[Constant]
[Final])

The following are examples of typical declared attributes:

 Q_PROPERTY(bool focus READ hasFocus) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
  • An Attribute acts like a data member of a class, but it also has additional features that can be operated by the metadata object system. These features are:
    A read accessors function is required. Read attribute value. Ideally, there is a constant function for this purpose, and it must return a value, pointer, or reference of the attribute type. For example, qwidget: focus is a read-only attribute that corresponds to a READ function: qwidget: hasfocus ().
  • An optional write accessors function. It is used to set the attribute value. It must return null and have at least one parameter, which is a value, pointer, or reference of the attribute type. For example, qwidget: enabled has the write function qwidget: setenable (). No function is required for read-only attributes. For example, qwidget: Focus does not have a corresponding write function.
  • An optional reset function. Set the attribute value to its default value. For example: qwidget: cursor has typical Read and Write Functions, qwidget: cursor () and qwidget: setcursor (), and it also has a reset function, qwidget :: unsetcursor (). The reset function must return void without any parameters.
  • An optional notify signal. If defined, the signal is sent when the attribute value changes. The signal must contain a parameter, which must be of the same type as the property. The parameter stores the new value of the property.
  • A designable variable indicates whether this attribute appears in the Attribute Editor of the interface designer. Most attributes are visible. Apart from passing true or false to this variable, you can also specify a bool-type member function.
  • The Scriptable variable indicates whether this attribute can be operated by a script engine (the default value is true ). You can also assign it a true, false, or bool function.
  • The stored variable indicates whether the attribute is considered independent or dependent on other values. It also indicates whether to save the value of this attribute when saving the object status. Most attributes need to be saved, but, for example, qwidget: minimumwidth () is not saved, because its value is obtained from another attribute qwidget: minimumsize.
  • The user variable indicates whether the attribute is designed as a user-oriented or user-modifiable class attribute. Generally, each class has only one user attribute. For example, qiniactbutton: checked is a button class that users can modify attributes. Note that qitemdelegate gets and sets the user attribute of the widget.
  • The appearance of Constant indicates that the attribute value remains unchanged. For an object instance, the read method of the constant attribute must return the same value each time it is called. This constant value may be different in different object instances. A constant attribute cannot have the write method or noyify signal.
  • The appearance of final variable indicates that the attribute cannot be overwritten by the derived class. In some cases, this can be used for efficiency optimization, but it is not forced by MOC. Programmers must always note that they cannot override a final attribute.

The read, write, and reset functions can be inherited. They can also be virtual functions. When they are inherited by multiple inheritance, they must appear in the first inherited class.

Attribute types can be all types supported by qvariant, or user-defined types. In the following example, the class qdate is treated as a user-defined type.
Q_property (qdate data read getdate write setdate)
Because qdate is user-defined, you must include the header file <qdate>.

For qmap, qlist, and qvaluelist attributes, the attribute value is a qvariant that contains the entire list or map. Note that the q_property string cannot contain commas, because commas divide macro parameters. Therefore, you must use qmap as the attribute type rather than qmap <qstring, qvariant>. To maintain consistency, you also need to use qlist and qvaluelist instead of qlist <qvariant> and qvaluelist <qvariant>.

Read/write attributes through the metadata Object System

A property can be read and written using the common functions qobject: Property () and qobject: setproperty (). You do not need to know the details of the class where the property is located, except the attribute name. In the following small code snippet, both qiniactbutton: setdown () and qobject: setproperty () are called to set the property to "down ".

 QPushButton *button = new QPushButton; QObject *object = button; button->setDown(true); object->setProperty("down", true);

Using the write operator to operate a property is better in the above two because it is fast and provides better diagnostic help during compilation, however, setting properties in this way requires you to understand the class during compilation. Using a name to manipulate attributes allows you to operate classes that you don't know in the compiler. You can find the attributes of a class at runtime by querying its qobject, qmetaobject, and qmetaproerties.

 QObject *object = ... const QMetaObject *metaobject = object->metaObject(); int count = metaobject->propertyCount(); for (int i=0; i<count; ++i) {     QMetaProperty metaproperty = metaobject->property(i);     const char *name = metaproperty.name();     QVariant value = object->property(name);     ... }

In the preceding code snippet, qmetaobject: Property () is used to obtain the metadata of attributes in an unknown class. Obtain the attribute name from metadata and pass it to qobject: Property () for retrieval.

A simple example

Suppose we have a class myclass, which is derived from qobject and uses the q_object macro in its private zone. We want to declare an attribute in the myclass class to keep track of a priorty value. The attribute value is called priority, and its type is an enumeration defined in the class myclass called priority.

We use q_property () in the private area of the class to declare the attribute. The READ function is called priority, and we include a write function called setpriority. The enumeration type must be registered to the metadata Object System Using q_enums. Register an enumeration type so that the enumeration name can be used when calling qobject: setproperty. We must also provide our own declaration for the Read and Write Functions. The declaration of myclass should look like this:

 class MyClass : public QObject {     Q_OBJECT     Q_PROPERTY(Priority priority READ priority WRITE setPriority)     Q_ENUMS(Priority) public:     MyClass(QObject *parent = 0);     ~MyClass();     enum Priority { High, Low, VeryHigh, VeryLow };     void setPriority(Priority priority);     Priority priority() const; };

The READ function is const and returns the type of the attribute. The Write function returns void and has an attribute type parameter. The metadata object compiler forces these tasks.

When there is a pointer to the myclass instance, we have two ways to set the priority attribute:

MyClass *myinstance = new MyClass; QObject *object = myinstance; myinstance->setPriority(MyClass::VeryHigh); object->setProperty("priority", "VeryHigh");

In this example, the enumeration type is declared in myclass and registered to the metadata Object System Using q_enums. This allows the enumerated value to be used as a string when setproperty () is called. If the enumeration type is declared in other classes, we need to use the full name of the enumeration (such as otherclass: Priority ), in addition, this other class must also be derived from qobject and the enumeration type must also be registered.
Another simple q_flags () is also available. Like q_enums (), it registers an enumeration type, but it uses the enumeration type as a flag set, that is, the values can be combined using the or operation. An I/O class may have the enumerated values read and write, and qobject: setproperty () can accept read | write. In this case, use q_flags () to register the enumerated values.

Dynamic attributes

Qobject: setproperty () can also be used to add new attributes to a class instance at runtime. When you call a name and value, if a corresponding property already exists and the value type is compatible with the property type, the value is stored in the property, then return true. If the value type is incompatible, the attribute value will not change and false will be returned. However, if the attribute of the corresponding name does not exist, a new attribute will be created. The attribute is named after the input name and the input value will be used as the value, but false will still be returned. This indicates that the returned value cannot be used to determine whether a property is set, unless you already know that this property already exists in qobject.
Note that dynamic attributes are added to the foundation of a single implementation, that is, they are added to qobject instead of qmetaobject. An attribute can be deleted from an instance by passing in the attribute name and an invalid qvariant value to qobject: setproperty (). The default qvariant constructor constructs an invalid qvariant.
Dynamic attributes can be queried using qobject: Property (). The attributes declared using q_property () are the same.

Attributes and custom types

The custom type used by the attribute needs to be registered using the q_declare_incluype () macro so that their values can be saved in the qvariant object. This allows them to be used in static types declared by q_property () or dynamic types.

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.