First, the object model
The standard C + + object model can be very effective at runtime to support the object paradigm (paradigm), but its static characteristics are inflexible in some problem areas. Graphical user interface programming requires a high degree of flexibility as well as high efficiency at runtime. For this reason, QT has added some features to the standard C + + object model to form its own object model. These features include:
- A powerful communication mechanism for seamless objects-signals and slots (signals and slots);
- Queryable and Customizable object property system (objects properties);
- Powerful event and event filters (events and events filters);
- A string translation mechanism that is internationalized through context (string translation for internationalization);
- The perfect Timer (timers) driver enables multiple tasks to be handled in an event-driven GUI;
- Hierarchical, Queryable object trees, which uses a natural way to organize objects ownership (object ownership);
- The guard pointer is Qpointer, which automatically sets the reference object to 0 when it is destroyed;
- Dynamic object transformation mechanism (dynamics cast);
These features of QT are implemented in accordance with the standard C + + specification, which must be inherited from the Qobject class. The object communication mechanism and the dynamic property system require the support of the meta-object System (Meta-objectsystem). For an introduction to the object model, you can see the object's model keyword in Help.
two, meta-object systemThe meta-object systems (Meta-object system) in QT provide signal and slot mechanisms for inter-object communication, runtime type information, and dynamic property systems. The meta-object system is based on the following three conditions:
- The class must inherit from the Qobject class;
- The Q_object macro must be declared in the private declaration area of the class (the default is private if no public or private is specified when the class is defined);
- The meta-object compiler Meta-object Compiler (MOC), which provides the necessary code for implementing the meta-object attributes of the Qobject subclass.
Where the MOC tool reads a C + + source file, if it discovers that one or more of the class's declarations contain a Q_object macro, it will create a separate C + + source file (the C + + source file that starts with the MOC in the project directory in the Debug directory). It contains the meta-object code generated for each class. The resulting source files are either included in the source file of the class, or are compiled and linked together with the implementation of the class.
The meta-object system was introduced primarily to implement signal and slot mechanisms, but in addition to the signal and slot mechanisms, the meta-object system provides additional features :
- The Qobject::metaobject () function can return a meta-object of a class, which is an object of the Qmetaobject class;
- Qmetaobject::classname () can return the class name as a string at run time without the support of the C + + editor's native run-time type information (RTTI) ;
- The Qobject::inherits () function returns information about whether an object is an instance of a class on the Qobject inheritance tree;
- Qobject::tr () and Qobject::trutf8 () perform string translation to achieve internationalization;
- Qobject::setproperty () and Qobject::p Roperty () dynamically set or Get object properties by name;
- Qmetaobject::newinstance () Constructs a new instance of the class.
In addition to these features, you can alsoUse the Qobject_cast () function to perform a dynamic type conversion of the Qobject class, which functions like the dynamic_cast () function in standard C + +, but it no longer requires RTTI support。 This function attempts to convert its arguments to a pointer of type in angle brackets, returns a nonzero pointer if the type is correct, and returns 0 if the type is incompatible. For example: qobject *obj = new Mywidget; Qwidget *widget = qobject_cast<qwidget *> (obj);
The signal and slot mechanism is the core of QT, and the signal and slot mechanisms must depend on the meta-object system, so it is qt critical content in the. knowledge of the meta-object system can beQtView inThe Meta-object Systemkey word.
third, Object Tree and ownershipQT uses the object tree to organize and manage all the objects of the Qobject class and its subclasses. When a qobject is created, the Qobject is added to the parent object's children () list if other objects are used as its parent, so that the qobject is destroyed when the parent object is destroyed. Practice has shown that this mechanism is well suited for managing GUI objects. For example, a qshortcut (keyboard shortcut) object is a sub-object of the corresponding window, so the shortcut can be destroyed when the user closes the window. Qwidgetas the base class for all the parts that can be displayed on the screen, the parent-child relationship between the objects is expanded. A sub-object is typically a subassembly, because they are displayed in the area of the parent part. For example, when you close a message dialog box (message boxwhen you destroy it, the buttons and labels in the message dialog box are also destroyed, which is exactly what we want because the buttons and labels are the child parts of the message dialog box. Of course, we can also destroy a sub-object by ourselves. For this part of the content, you can see in the Help indexObject Trees &ownershipkey word. in front of theQtin programming we should have seen a lot of useNewto create a part, but it is not usedDeleteto release the issue. Let's look at the problem here. NewQt Guiapplication, the project name is "Myownership", base class selectionQwidget, and then the class name remains "Widgets"does not change. When you are finished adding a new file to the project, select the templateC + + Class, the class is named "MyButton", the base class is"Qpushbutton", type information selection" inherits fromQwidget". After you have finished adding files ,Mybutton.hthe declaration of the Add destructor in the file:~
MyButton();Then add the header file to the Mybutton.cpp file # include <QDebug> and define the destructor:MyButton:: ~
MyButton(){ qdebug () << "Delete button";}
So whenMyButtonwhen the object is destroyed, the corresponding information is output. The destructor is defined here, but in order to see the destruction process of the part more clearly, it is generally not necessary to implement the destructor when constructing the new class . Below theWidget.cppfile, add the header file:#include "Mybutton.h"#include <QDebug>
Add code to the constructor:MyButton *Button = New MyButton( This); // creates a button part, specifyingWidgetsas parent partbutton->SetText (Tr ("button"));
To change the destructor:Widgets:: ~
widgets(){ Delete ui; qdebug () << "Delete widget";}
Widgetsclass is destroyed by default in the destructor of theUistatement, and the output statement is added here. WhenWidgetswhen the window is destroyed, the information is output. Run the program below, then close the window,Qtcreatorthe output information in the application output bar is:Delete WidgetDelete button As you can see, when the window is closed, because the window is the top-level window, the application destroys the widget (if it is not a top-level window, it is hidden when it is closed, is not destroyed), and its child parts are destroyed automatically when the widget is destroyed. This is whyQtare often seen only inNewoperation and cannot seeDeletethe cause of the operation. Look again .Main.cppfile, where WidgetsThe object is built on the stack:Widgets W;W.Show (); for Object W, it isautomatically destroyed when the program is closed. For widgets in widgets, if they are created on the heap (using the new operator), it is possible to specify the widget as its parent window, and no delete operation is required . When the entire application shuts down, the W object is destroyed, and all its subassemblies are automatically destroyed, which is done by the Qt object tree. So, for the canonical Qt program, we are going to create the main window part on the stack in the main () function, for example "Widget W;" instead of being created on the heap (using the new operator). For other widgets, you can use the new operator to create on the heap, but be sure to specify its parent part so that you do not need to use the delete operator again to destroy the object.
There is also a redefinition of the parent part (reparented, For example, if you apply a layout manager that contains other parts to a window, the layout manager and all of its parts automatically convert their parent parts to that widget. In theWidget.cppadd a header file to the file#include <QHBoxLayout>, and then continue adding code in the constructor:MyButton *button2 = New MyButton;MyButton *button3 = New MyButton;Qhboxlayout *layout = New Qhboxlayout;layout->AddWidget (button2);layout->AddWidget (button3);setlayout (layout); // use the Layout manager in this windowThere are two createdMyButtonand a horizontal layout manager, but does not specify their parent part, now ownership of the individual parts (Ownership) is not very clear. However, when you use the Layout Manager to manage both buttons, and the layout manager is used in the window, both buttons and the horizontal layout manager redefine the parent part as the windowWidgetsSub-parts. can useChildren ()function to get a list of all child parts of a part, such as adding the following code to the constructor:Qdebug () << children ();// output A list of all child parts then you can run the program, look at the application output bar information, and then according to their own ideas to change the program, to further understandQtthe concept of the object tree in the.
Iv. Summarythe object tree in Qt is a good solution to the relationship between parent and child parts, which is very convenient for Gui programming, and we only need to focus on its parent part when creating a part.
This will eliminate the need to consider the problem of destruction . In the next section, we will explain the contents of the signals and slots in Qt.
Object Tree and Ownership