📄 moc.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Qt Toolkit - Using the Meta Object Compiler</title><style type="text/css"><!--h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; }a:link { color: #004faf; text-decoration: none }a:visited { color: #672967; text-decoration: none }body { background: white; color: black; }--></style></head><body bgcolor="#ffffff"><p><table width="100%"><tr><td><a href="index.html"><img width="100" height="100" src="qtlogo.png"alt="Home" border="0"><img width="100"height="100" src="face.png" alt="Home" border="0"></a><td valign="top"><div align="right"><img src="dochead.png" width="472" height="27"><br><a href="classes.html"><b>Classes</b></a>- <a href="annotated.html">Annotated</a>- <a href="hierarchy.html">Tree</a>- <a href="functions.html">Functions</a>- <a href="index.html">Home</a>- <a href="topicals.html"><b>Structure</b> <font face="Arial,Helvetica,Geneva,Swiss,SunSans-Regular" align="center" size=32>Qte</font></a></div></table><h1 align="center"> Using the Meta Object Compiler</h1><br clear="all">The Meta Object Compiler, moc among friends, is the program whichhandles the <a href="metaobjects.html">C++ extensions in Qt.</a><p>The moc reads a C++ source file. If it finds one or more classdeclarations that contain the "Q_OBJECT" macro, it produces anotherC++ source file which contains the meta object code for thisclass. Among other things, meta object code is required for thesignal/slot mechanism, runtime type information and the dynamicproperty system.<p>The C++ source file generated by the moc must be compiled and linkedwith the implementation of the class (or it can be #included into theclass' source file).<p>Using the moc is introduced in <a href="t7.html">chapter 7</a> of theQt Tutorial. Chapter 7 includes a simple <a href="t7-makefile.html">Makefile that uses the moc</a> and of course source code thatuses signals and slots.<p><h2>Usage</h2><p>The moc is typically used with an input file containing class declarationslike this skeleton:<p><pre> class MyClass : public QObject { Q_OBJECT public: MyClass( <a href="qobject.html">QObject</a> * parent=0, const char * name=0 ); ~MyClass(); signals: void mySignal(); public slots: void mySlot(); };</pre><p> In addition to the signals and slots shown above, the moc alsoimplements object properties as in the next skeleton. The "Q_PROPERTY"macro declares an object property, while "Q_ENUMS" declares a list ofenumeration types within the class to be usable inside the propertysystem. In this particular case we declare a property of theenumeration type <code>Priority</code> that is also called "priority" and has aget function <code>priority()</code> and a set function <code>setPriority().</code><p><pre> class MyClass : public QObject { Q_OBJECT Q_PROPERTY( Priority priority READ priority WRITE setPriority ) Q_ENUMS( Priority ) public: MyClass( <a href="qobject.html">QObject</a> * parent=0, const char * name=0 ); ~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow }; void setPriority( Priority ); Priority priority() const; };</pre><p> Properties can be modified in subclasses with the "Q_OVERRIDE"macro. The "Q_SETS" macro declares enums to actually be used assets. Another macro "Q_CLASSINFO" can be used to attach additionalname/value-pairs to the classes' meta object:<p><pre> class MyClass : public QObject { Q_OBJECT Q_CLASSINFO( "Author", "Oscar Peterson") Q_CLASSINFO( "Status", "Very nice class") public: MyClass( <a href="qobject.html">QObject</a> * parent=0, const char * name=0 ); ~MyClass(); };</pre><p> The three concepts, signals and slots, properties and classinformations, can be combined.<p>The output produced by the moc must be compiled and linked, just asthe other C++ code of your program; otherwise the building of yourprogram will fail in the final link phase. By convention, this is donein one of the following two ways:<p><dl><p><dt><b>Method A: The class declaration is found in a header(<var>.h</var>) file</b><p><dd>If the class declaration above is found in the file<var>myclass.h</var>, the moc output should be put in a file called<var>moc_myclass.cpp</var>. This file should then be compiled asusual, resulting in an object file <var>moc_myclass.o</var> (on Unix)or <var>moc_myclass.obj</var> (on Windows). This object should then beincluded in the list of object files that are linked together in thefinal building phase of the program.<p><dt><b>Method B: The class declaration is found in an implementation(<var>.cpp</var>) file</b><p><dd>If the class declaration above is found in the file<var>myclass.cpp</var>, the moc output should be put in a file called<var>myclass.moc</var>. This file should be #included in theimplementation file, i.e. <var>myclass.cpp</var> should contain theline<br><var>#include "myclass.moc"</var><br> after the other code. Thiswill cause the moc-generated code to be compiled and linked togetherwith the normal class definition in <var>myclass.cpp</var>, so it isnot necessary to compile and link it separately, as in Method A.<p></dl><p>Method A is the normal method. Method B can be used in cases whereone for some reason wants the implementation file to beself-contained, or in cases where the Q_OBJECT class isimplementation-internal and thus should not be visible in the headerfile.<p><h2>Automating moc Usage with Makefiles</h2><p>For anything but the simplest test programs, it is recommended toautomate the running of the moc. By adding some rules to the Makefileof your program, <var>make</var> can take care of running moc whennecessary and handling the moc output.<p>We recommend using Trolltech's free makefile generation tool<var>tmake</var> for building your Makefiles. This tool recognizesboth Method A and B style source files, and generates a Makefile thatdoes all necessary moc handling. tmake is available from <ahref="http://www.trolltech.com/freebies/tmake.html">http://www.trolltech.com/freebies/tmake.html</a>.<p>If, on the other hand, you want to build your Makefiles yourself,here are some tips on how to include moc handling.<p>For Q_OBJECT class declarations in header files, here is a usefulmakefile rule if you only use GNU make:<p><pre> moc_%.cpp: %.h moc $< -o $@</pre><p><p>If you want to write portably, you can use individual rules of thefollowing form:<p><pre> moc_NAME.cpp: NAME.h moc $< -o $@</pre><p><p>You must also remember to add <var>moc_NAME.cpp</var> to your SOURCES(substitute your favorite name) variable and <var>moc_NAME.o</var> or<var>moc_NAME.obj</var>to your OBJECTS variable.<p><p>(While we prefer to name our C++ source files .cpp, the moc doesn'tknow that, so you can use .C, .cc, .CC, .cxx or even .c++ if youprefer.)<p><p>For Q_OBJECT class declarations in implementation (.cpp) files, wesuggest a makefile rule like this:<p><pre> NAME.o: NAME.moc NAME.moc: NAME.cpp moc -i $< -o $@</pre><p><p>This guarantees that make will run the moc before it compiles<var>NAME.cpp.</var> You can then put<p><pre> #include "NAME.moc"</pre><p>at the end of <var>NAME.cpp,</var> where all the classes declared inthat file are fully known.<p><h2>Invoking moc</h2><p>Here are the command-line options supported by the moc:<p><dl><dt> -o <var>file</var> <dd> Write output to <var>file</var> ratherthan to stdout.<dt> -f <dd> Force the generation of an #include statement in theoutput. This is the default for files whose name matches the regularexpression \.[hH][^.]* (ie. the extension starts with H or h). Thisoption is only useful if you have header files that do not follow thestandard naming conventions.<dt> -i <dd> Do not generate an #include statement in the output.This may be used to run the moc on on a C++ file containing one ormore class declarations. You should then #include the meta objectcode in the .cppfile. If both -i and -f are present, the last one wins.<dt> -nw <dd> Do not generate any warnings. Discouraged.<dt> -ldbg <dd> Write a flood of lex debug information on stdout.<dt> -p <var>path</var> <dd> Makes the moc prepend <var>path</var>/ tothe file name in the generated #include statement (if one isgenerated).<dt> -q <var>path</var> <dd> Makes the moc prepend <var>path</var>/ tothe file name of qt #include files in the generated code.</dl><p>You can explicitly tell the moc to not parse parts of a headerfile. It recognizes any C++ comment (//) that contains the substringsMOC_SKIP_BEGIN or MOC_SKIP_END. They work as you would expect and youcan have several levels of them. The net result as seen by the moc isas if you had removed all lines between a MOC_SKIP_BEGIN and aMOC_SKIP_END<p><h2>Diagnostics</h2><p>The moc will warn you about a number of dangerous or illegalconstructs in the Q_OBJECT class declarations.<p>If you get linkage errors in the final building phase of yourprogram, saying that YourClass::className() is undefined or thatYourClass lacks a vtbl, something has been done wrong. Most often,you have forgot to compile or #include the moc-generated C++ code, or(in the former case) include that object file in the link command.<p><h2>Limitations</h2><p>The moc does not expand #include or #define, it simply skips anypreprocessor directives it encounters. This is regrettable, but isnormally not a problem in practice.<p>The moc does not handle all of C++. The main problem is that classtemplates cannot have signals or slots. Here is an example:<p><pre> class SomeTemplate<int> : public QFrame { Q_OBJECT [...] signals: void bugInMocDetected( int ); };</pre><p>Less importantly, the following constructs are illegal. All of themhave alternatives which we think are usually better, so removing theselimitations is not a high priority for us.<p><h4>Multiple inheritance requires QObject to be first</h4><p>If you are using multiple inheritance, moc assumes that the <em>first</em>inherited class is a subclass of QObject. Also, be sure that <em>only</em>the first inherited class is a QObject.<p><pre> class SomeClass : public QObject, public OtherClass { [...] };</pre><p>(This limitation is almost impossible to remove; since the moc does not expandis a QObject.)<p><h4>QObject may not be virtually inherited</h4><p>You can not use virtual inheritance in the QObject branch of theinheritance tree. The following example shows one wrong and onecorrect class declaration:<p><pre> class Wrong : virtual public QObject, virtual public OtherClass { [...] };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -