Inherited qtreewidgetitem error: 'staticmetaobject' is not a member of 'qtreewidgetitem &#

Source: Internet
Author: User
Tags qt designer

# Ifndefqquseritem_h:

# Defineqquseritem_h # include <qtreewidgetitem> classqquseritem: Role {q_objectpublic: explicitqquseritem (qquseritem * parent = 0); signals: publicslots :}; # endif/qquseritem_h

Debug \ moc_qquseritem.cpp: 41: 8: Error: 'staticmetaobject' is not a member of 'qtreewidgetitem'

 

... \ .. \ QT \ 4.6.3 \ include/qtcore/http://www.cnblogs.com/src/corelib/kernel/qobject.h: in member function 'virtual const qmetaobject * qquseritem: metaobject () const ':

 

... \ .. \ QT \ 4.6.3 \ include/qtcore/http://www.cnblogs.com/src/corelib/kernel/qobject.h:296:33: error: 'qscopedpointer <qobjectdata> qobject: d_ptr 'is protected

 

Debug \ moc_qquseritem.cpp: 51: 21: Error: within this context

 

... \ .. \ QT \ 4.6.3 \ include/qtcore/http://www.cnblogs.com/src/corelib/kernel/qobject.h:296:33: error: Object missing in reference to 'qobject: d_ptr'

 

Debug \ moc_qquseritem.cpp: 51: 21: Error: from this location

 

... \ .. \ QT \ 4.6.3 \ include/qtcore/http://www.cnblogs.com/src/corelib/kernel/qobject.h:296:33: error: 'qscopedpointer <qobjectdata> qobject: d_ptr 'is protected

 

Debug \ moc_qquseritem.cpp: 51: 50: Error: within this context

 

... \ .. \ QT \ 4.6.3 \ include/qtcore/http://www.cnblogs.com/src/corelib/kernel/qobject.h:296:33: error: Object missing in reference to 'qobject: d_ptr'

 

Debug \ moc_qquseritem.cpp: 51: 50: Error: from this location

 

Debug \ moc_qquseritem.cpp: In member function 'virtual void * qquseritem: qt_metacast (const char *)':

 

Debug \ moc_qquseritem.cpp: 59: 12: Error: 'qt _ metacast 'is not a member of 'qtreewidgetitem'

 

Debug \ moc_qquseritem.cpp: In member function 'virtual int qquseritem: qt_metacall (qmetaobject: Call, Int, void **)':

 

Debug \ moc_qquseritem.cpp: 64: 11: Error: 'qt _ metacall' is not a member of 'qtreewidgetitem'

 

Debug \ moc_qquseritem.cpp: In member function 'virtual void * qquseritem: qt_metacast (const char *)':

 

Debug \ moc_qquseritem.cpp: 60: 1: Warning: control reaches end of non-void Function

 

Debug \ moc_qquseritem.cpp: In member function 'virtual const qmetaobject * qquseritem: metaobject () const ':

 

Debug \ moc_qquseritem.cpp: 52: 1: Warning: control reaches end of non-void Function

 

Mingw32-make [1]: *** [debug/moc_qquseritem.o] Error 1

 

Mingw32-make: *** [debug] Error 2

 

The process "D:/mingw/bin/mingw32-make.exe" exited with code % 2.

Error while building project myqq (target: desktop)

When executing build step 'make'

Changed to classqquseritem: publicqobject and publicqtreewidgetitem. The following information is found:

The following error occurs: 'staticmetaobject' is not a member of 'ui: mainwindow'

 

This kind of design was first introduced from Borland C ++ builder. As a so-called rapid development tool, in fact, I have no clear understanding of its implementation interface design. Later, I came into contact with Java for a period of time. At that time, I only knew that my own design interface was to inherit a class, such as the main window or applet, and then added many other components to the class as its protected member. However, it is seldom considered how to design more conveniently. Therefore, it can be said that the first GUI library that comes into contact with this design idea is in QT. I have to say that QT is actually very similar to Java. Although QT is written in C ++, it is noticed that it is the same as a single ancestor qobject. rtti implemented through qmetaobject, this is more or less the same as Java's single ancestor, but QT does not reject the use of other C ++ classes, but only loses the signal/slot mechanism. In the man page of MOC, the limitations of QT implementation are described as follows:

We cannot use template to inherit qobject. In other words, the following code cannot be converted into valid C ++ compiler code by MoC:
Template <class>

Class templateclass: Public qobject {
Q_object
//...
Public slots:
//...
}; Class>
To use multiple inheritance, You must place the qobject or its subclass at the first parent class (because the q_object must be overwritten) and inherit other classes. If G ++ is reversed, an error occurs, as shown in figure
Multiclass. HPP: 17: Warning: Class multiclass inherits from two qobject subclasses noneqtclass and qobject. This is not supported!
Moc_multiclass.cpp: 39: Error: 'staticmetaobject' is not a member of 'noneqtclass'
Moc_multiclass.cpp: In member function 'virtual void * multiclass: qt_metacast (const char *)':
Moc_multiclass.cpp: 55: Error: 'qt _ metacast 'is not a member of 'noneqtclass'
Moc_multiclass.cpp: In member function 'virtual int multiclass: qt_metacall (qmetaobject: Call, Int, void **)':
Moc_multiclass.cpp: 60: Error: 'qt _ metacall' is not a member of 'noneqtclass'
Make: *** [moc_multiclass.o] Error 1 multiclass inherits qobject and noneqtclass. After the inserted q_object is expanded, because the structure of multiclass after placing noneqtclass first is no longer a qobject, an error occurred while creating staticmetaobject. Because the following virtual function table is followed, the vtable of the previous class is actually used.

Function pointers cannot be used as signal/slot parameters, which can be overcome by typedef, as shown in
Class someclass: Public qobject
{
Q_object
//...
Public slots:
// Illegal
Void apply (void (* apply) (list *, void *), void *);
}; Will be considered invalid (mainly because it fails to judge the parameter type. Do you remember what information is stored in qmetaobject ?), However

Typedef void (* applyfunctiontype) (list *, void *);

Class someclass: Public qobject
{
Q_object
//...
Public slots:
Void apply (applyfunctiontype, char *);
}; Is feasible.

It is recommended that you do not place the object meta statement in the signal and slot statements. This is obvious because, in most cases, signals: is replaced with protected:, and slots is replaced with null, however, the compiler may not be completely unrelated to processing friend. Theoretically, the standard compiler should be able to work, such as G ++ 4.3.3.
Signal and slot cannot be upgrade. This is because MOC requires a complete function declaration, and the declaration is incomplete during the upgrade, as shown in
Class slotclass: Public qobject
{
Q_object
Protected slots:
Int getvalue ();
};

Class upgradeslotclass: Public slotclass
{
Q_object
Public slots:
Slot: getvalue;
}; The slot: getvalue is allowed under normal conditions. It can be seen that the error is MOC,

/Usr/bin/moc-qt4-dqt_no_debug-dqt_gui_lib-dqt_core_lib-dqt_shared-I/usr/share/qt4/mkspecs/Linux-G ++-I. -I/usr/include/qt4/qtcore-I/usr/include/qt4/qtgui-I/usr/include/qt4-I. -I. -I. upgradeslotclass. HPP-O moc_upgradeslotclass.cpp
Upgradeslotclass. HPP: 15: Error: not a signal or slot declarationsignal and slot parameters cannot use macros, because MOC does not expand macros.
The nested class declaration should not appear in signal or slot. It is also because MOC cannot handle it.
Constructors should not appear in signal and slot. Although they are functions, they are not necessary.
Q_property macro description attributes must be written in the same public section that contains the read/write functions. Note:
# Define q_property (text) does not function in class declaration, but MOC compilation generates the corresponding code, and MoC requires this part to be written in a similar way.

Class propertyclass: Public qobject
{
Q_object
Q_property (INT value read getvalue write setvalue)
Int value;
Public:
Propertyclass ();
Void setvalue (Int = 0 );
Int getvalue () const;
}; The MOC generates the following code.

Int propertyclass: qt_metacall (qmetaobject: Call _ c, int _ id, void ** _)
{
_ Id = qobject: qt_metacall (_ c, _ id, _ );
If (_ id <_ c = "=" _ v = "_ A [0];" _ c = "=" _ v = "_ A [0]; "_ c =" = "_ c =" _ c = "=" _ c = "=">
Why does it seem unnecessary to support property and q_classinfo in qmetaobject? For example

Q_classinfo ("version", "3.0.0 ")
This actually provides support for GUI Design programs in one aspect. The GUI Design Program provided by QT is called QT designer (it seems that QT creator can also be designed). This is a graphical interface. Drag the required widgets to the window and organize them with appropriate layout, when each widget is clicked, there is a property editor. Here, you can set the attribute declared by q_property and set designable to true. This is called the widget editing mode. In addition, there is also signal and slot editing mode. Here we can drag the widget that sends signal directly to the slot. This will generate an arrow and fill in the corresponding signal and slot. In buddy editing mode, we Drag widgets that do not accept keyboard response in principle to the relevant widgets that accept keyboard response, which gives them the ability to process the keyboard in an equal effect. In the tab order mode, we set the order of traversal by tab. In addition, there is a resource editor for us to manage resources, such as images used, Action editor allows us to edit the action on the menu (and finally connect the menu item or toolbar with it ). The new quiloader class allows QT to process the XML file description interface like glade and generate it dynamically.

Qt provides more than just some widgets (compared with gtkmm). It also provides support for accessibility, Database SQL, and network modules. This will be discussed later. Here we will focus on some design features of QT designer.

In QT designer, you can preview the skin and add your own stylesheet similar to CSS to change the widget style. You can use the preview in Settings> preference> form to open the widget, or click stylesheet of a widget to add it. The commonly used container in QT includes frame, groupbox, stackedwidget, tabwidget, toolboxwidget, and dockwidget. We can put other widgets in it.

The QT design menu and toolbar are simple. interfaces and functions are designed separately. You can add menu items in the editing status and click the corresponding place as required. & A keyboard operation can be generated in the menu, for example, & file will make the menu open properly and then press F to call the menu. Similarly, you can add some buttons on the toolbar. The function is edited using action editor.

Next we will look at how to combine the interface designed by QT designer with our program. First, you must understand the output of QT designer. how the UI file will be processed at the end, which is processed by the UIC program. h file, such as mywindow. the UI will generate a ui_my1_1_h file, which contains two parts, one of which is the ui_mywindow class. This class actually only contains all the widgets except the top-layer widgets, for example, if we use the qmainwindow or qwidget class in our window, there are several layout and buttons in it, then the generated ui_mywindow class contains pointers of all components except qmainwindow and qwidget, the setupui (qmainwindow *) method is used to display the interface we designed on the specified top-level widget. In addition, a mywindow class is declared in the UI Domain Name Space, inheriting from ui_mywindow, to avoid namespace pollution. Therefore, the simplest way to preview a form is to use the following code,

# Include "ui_main.h"

Int main (INT argc, char * argv [])
{
Qapplication app (argc, argv );
Qmainwindow * widget = new qmainwindow;
Ui: mainwindow UI;
Ui. setupui (widget );
Widget-> show ();
Return app.exe C ();
}
We will analyze the code in detail later. Here, we will generate a qmainwindow through new, and then use UI: mainwindow to generate a class entity that only generates code, and call the setupui () method to generate the interface we need on the widget. Finally, call the show () method of the widget and start to enter the message loop with app.exe C.

Insert a section about the widget release. Note that the widgets generated by calling new in the UI are destroyed when the widget is destroyed. The widgets in the UI are not parsed, in fact, the last step is dangling pointer, which is very dangerous. Do not do this step. In addition, when the window is closed, the slot qmainwindow: Close () is triggered, which will analyze the form (if the qwidget: deleteonclose attribute is set ).

However, we can add a very simple signal/slot connection to QT designer at most. There are many other functions that we do not implement in QT designer. Therefore, we need to use other methods to implement our own functions without modifying this part of the automatically generated code. The simplest way is to inherit the Form class and use the interface as a private member,

Class mywindow: Public qmainwindow
{
//...
PRIVATE:
Ui: mywindow UI;
};
In this way, you can create your own interface through UI (this) when constructing mywindow: mywindow (), and then modify the signal/slot connection through functions such as qobject: connect. However, the connection must be performed through the member UI.

It is more convenient to use multiple inheritance,

Class mywindow: Public qmainwindow, private UI: mywindow
{
//...
Public:
Mywindow (qwidget * P): qmainwindow (P), UI: mywindow (){
Setupui (this );
//...
}
};
In this case, we can connect mywindow: component directly. However, it is worth noting that connect can only be performed between qobjects and cannot be passed to non-qobject objects or connect to common functions.

The other is similar to the glade implementation,

Qwidget * textfinder: loaduifile ()
{
Quiloader;

Qfile file (":/Forms/textfinder. UI ");
File. Open (qfile: readonly );

Qwidget * formwidget = loader. Load (& file, this );
File. Close ();

Return formwidget;
}
Note that the dynamic loading cannot be called in the form of formwidget-> member. We should use qobject: objectname () to search for the corresponding address, as shown in

Ui_findbutton = qfindchild (this, "findbutton ");
We will compare the differences between gtkmm in implementing similar functions later.

The most common method to create a connection is to create a connection manually, because the connection must be connected to a qobject, so the most direct method is as follows:

Imagedialog: imagedialog (qwidget * parent)
: Qdialog (parent)
{
Setupui (this );
Okbutton-> setautodefault (false );
Cancelbutton-> setautodefault (false );
//...
Connect (okbutton, signal (clicked (), this, slot (checkvalues ()));
}
Put the slot in multiple private slots that inherit qobject. However, QT can use qmetaobject to implement automatic connections. This is the slots defined by on_objectname_signal, and qmetaobject: connectslotsbyname (qobject *) connection, such as multi-inheritance, this is taken, and the widget pointer returned by quiloader: load () is used for the interface generated from the UI file. Generally, the UIC-generated code automatically calls this function.

 

A link error occurs. The program structure is very simple, that is, the designer designs the main interface and uses multiple inheritance methods in the Code. The strange error information is as follows:

Moc_mainwin.cpp: 39: Error: 'staticmetaobject' is not a member of 'ui: mainwindow'
Moc_mainwin.cpp: In member function 'virtual void * mainwin: qt_metacast (const char *) ': moc_mainwin.cpp: 56: Error: 'qt _ metacast' is not a member of 'mainwin :: qt_metacast (const char *): qmocsuperclass'
Moc_mainwin.cpp: In member function 'virtual int mainwin: qt_metacall (qmetaobject: Call, Int, void **) ': moc_mainwin.cpp: 62: Error: 'qt _ metacall' is not a member of 'mainwin: qt_metacall (qmetaobject: Call, Int, void **): qmocsuperclass'
Make: *** [moc_mainwin.o] Error 1

Does the MOC file automatically generated by QT still cause compilation errors? This is a bit incredible. I took the project and saw it from the beginning and didn't see any errors, which may lead to this link error. N after a long time, the warnings reported in a compilation phase caught the attention of the author. The general idea is that multi-inheritance cannot be inherited from two qobject classes, which is strange, how does it regard my UI class as derived from qobject? With this prompt, I try to modify the line of code for multiple inheritance:

Class mainwin: Public UI: mainwindow, public qwidget

Change

Class mainwin: Public qwidget, public UI: mainwindow

What do you guess? Miracle happened ...... Haha, compilation successful! It turns out to be a problem caused by the inheritance sequence. Is this a QT bug? I sent a bug report to trolltech support and got the following answer:

This is actually a known limitation which has been authorized ented for some time, when using multiple inheritance you have to specify the qobject based class first and then the other class. Its mentioned in the documentation:

Http://doc.trolltech.com/4.5/moc.html

Under the limitations section.

It turns out like Peter! It seems that this is not enough. Such an important document never knows its existence.

Read carefully and find that there are still many restrictions on MOC-related programming in QT. You may also receive further education:

MoC Functions

1. process the q_object macro and signals/slots keywords to generate the underlying code of the signal and slot

2. Process q_property () and q_enum () to generate the property system code

3. Process q_flags () and q_classinfo () to generate additional class meta information

4. The code that does not require MOC processing can be included in a predefined macro, as shown below:

# Ifndef q_moc_run
...
# Endif

MoC restrictions (too many, dazzling)

1. The template class cannot use the signal/Slot Mechanism

2. MoC does not expand macros, so macros cannot be used for signal and slot definitions, including macro names and parameters for signals and slots during connect.

3. When deriving from multiple classes, the qobject derived class must be placed in the first one, because MOC thinks so... (ROGUE) This is the day we used in the previous example.

4. The function pointer cannot be used as a signal or Slot Parameter. Because of its complicated format, MoC cannot process it. However, typedef can be used to define it as a simple form. (This is an amazing move)

5. Fully Qualified is required when the enumeration type or typedef type is used as the signal and slot parameters. It is appropriate to translate this word in Chinese without knowing how to translate it. Simply put, if it is defined in a class, the class path or namespace path must be added to prevent confusion. For example, QT: alignment. The previous QT is the qualifier of alignment. It must be added with several levels.

6. The signal and slot cannot return the reference type.

7. The signals and slots keyword areas can only be defined by signals and slots, but cannot be defined by other variables.

Well, these restrictions seem like unequal treaties. Are they very eye-catching? In fact, some of these restrictions should be discussed as bugs, but they have little impact on QT programming and can be ignored temporarily, therefore, the problem is handled (meaning it may never be changed ).

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.