diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /doc/html/moc.html | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'doc/html/moc.html')
-rw-r--r-- | doc/html/moc.html | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/doc/html/moc.html b/doc/html/moc.html new file mode 100644 index 0000000..5861d95 --- /dev/null +++ b/doc/html/moc.html @@ -0,0 +1,452 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/moc.doc:39 --> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Using the Meta Object Compiler</title> +<style type="text/css"><!-- +fn { margin-left: 1cm; text-indent: -1cm; } +a:link { color: #004faf; text-decoration: none } +a:visited { color: #672967; text-decoration: none } +body { background: #ffffff; color: black; } +--></style> +</head> +<body> + +<table border="0" cellpadding="0" cellspacing="0" width="100%"> +<tr bgcolor="#E5E5E5"> +<td valign=center> + <a href="index.html"> +<font color="#004faf">Home</font></a> + | <a href="classes.html"> +<font color="#004faf">All Classes</font></a> + | <a href="mainclasses.html"> +<font color="#004faf">Main Classes</font></a> + | <a href="annotated.html"> +<font color="#004faf">Annotated</font></a> + | <a href="groups.html"> +<font color="#004faf">Grouped Classes</font></a> + | <a href="functions.html"> +<font color="#004faf">Functions</font></a> +</td> +<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Using the Meta Object Compiler</h1> + + + +<p> <!-- index moc --><a name="moc"></a> +<p> The Meta Object Compiler, moc among friends, is the program which +handles Qt's <a href="metaobjects.html">C++ extensions.</a> +<p> The moc reads a C++ source file. If it finds one or more class +declarations that contain the <a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a> macro, it produces another +C++ source file which contains the <a href="metaobjects.html#meta-object">meta object</a> code for the classes +that use the Q_OBJECT macro. Among other things, meta object code is +required for the signal/slot mechanism, runtime type information and +the dynamic property system. +<p> The C++ source file generated by the moc must be compiled and linked +with the implementation of the class (or it can be #included into the +class's source file). +<p> If you use <a href="qmake-manual.html">qmake</a> to create your +Makefiles, build rules will be included that call the moc when +required, so you will not need to use the moc directly. For more +background information on moc, see <a href="templates.html">Why doesn't Qt +use templates for signals and slots?</a>. +<p> <h2> Usage +</h2> +<a name="1"></a><p> The moc is typically used with an input file containing class declarations +like this: +<p> <pre> + class MyClass : public <a href="qobject.html">QObject</a> + { + 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 also +implements object properties as in the next example. The Q_PROPERTY +macro declares an object property, while Q_ENUMS declares a list of +enumeration types within the class to be usable inside the +<a href="properties.html">property system</a>. In this particular +case we declare a property of the enumeration type <tt>Priority</tt> that is +also called "priority" and has a get function <tt>priority()</tt> and a set +function <tt>setPriority()</tt>. +<p> <pre> + class MyClass : public <a href="qobject.html">QObject</a> + { + 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 that are to be used as +sets, i.e. OR'ed together. Another macro, Q_CLASSINFO, can be used to +attach additional name/value-pairs to the class' meta object: +<p> <pre> + class MyClass : public <a href="qobject.html">QObject</a> + { + Q_OBJECT + Q_CLASSINFO( "Author", "Oscar Peterson") + Q_CLASSINFO( "Status", "Active") + 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 class +meta-data, can be combined. +<p> The output produced by the moc must be compiled and linked, just like +the other C++ code in your program; otherwise the build will fail in +the final link phase. By convention, this is done in one of the +following two ways: +<p> <dl> +<p> <dt><b>Method A: The class declaration is found in a header +(<em>.h</em>) file</b> +<p> <dd>If the class declaration above is found in the file +<em>myclass.h</em>, the moc output should be put in a file called +<em>moc_myclass.cpp</em>. This file should then be compiled as +usual, resulting in an object file <em>moc_myclass.o</em> (on Unix) +or <em>moc_myclass.obj</em> (on Windows). This object should then be +included in the list of object files that are linked together in the +final building phase of the program. +<p> <dt><b>Method B: The class declaration is found in an implementation +(<em>.cpp</em>) file</b> +<p> <dd>If the class declaration above is found in the file +<em>myclass.cpp</em>, the moc output should be put in a file called +<em>myclass.moc</em>. This file should be #included in the +implementation file, i.e. <em>myclass.cpp</em> should contain the +line +<pre> + #include "myclass.moc" +</pre> + +at the end. This will cause the moc-generated code to be compiled and +linked together with the normal class definition in <em>myclass.cpp</em>, so +it is not 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 where you +want the implementation file to be self-contained, or in cases where +the Q_OBJECT class is implementation-internal and thus should not be +visible in the header file. +<p> <h2> Automating moc Usage with Makefiles +</h2> +<a name="2"></a><p> For anything but the simplest test programs, it is recommended that +you automate running the moc. By adding some rules to your program's +Makefile, <em>make</em> can take care of running moc when necessary and +handling the moc output. +<p> We recommend using Trolltech's free makefile generation tool, <a href="qmake-manual.html">qmake</a>, for building your Makefiles. This tool +recognizes both Method A and B style source files, and generates a +Makefile that does all the necessary moc handling. +<p> If you want to create 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 useful +makefile rule if you only use GNU make: +<p> <pre> + moc_%.cpp: %.h + moc $< -o $@ +</pre> + +<p> If you want to write portably, you can use individual rules with the +following form: +<p> <pre> + moc_NAME.cpp: NAME.h + moc $< -o $@ +</pre> + +<p> You must also remember to add <em>moc_NAME.cpp</em> to your SOURCES +(substitute your favorite name) variable and <em>moc_NAME.o</em> or +<em>moc_NAME.obj</em> to your OBJECTS variable. +<p> (While we prefer to name our C++ source files .cpp, the moc doesn't +care, so you can use .C, .cc, .CC, .cxx or even .c++ if you +prefer.) +<p> For Q_OBJECT class declarations in implementation (.cpp) files, we +suggest a makefile rule like this: +<p> <pre> + NAME.o: NAME.moc + + NAME.moc: NAME.cpp + moc -i $< -o $@ +</pre> + +<p> This guarantees that make will run the moc before it compiles +<em>NAME.cpp</em>. You can then put +<p> <pre> + #include "NAME.moc" +</pre> + +<p> at the end of <em>NAME.cpp</em>, where all the classes declared in +that file are fully known. +<p> <h2> Invoking moc +</h2> +<a name="3"></a><p> Here are the command-line options supported by the moc: +<p> <center><table cellpadding="4" cellspacing="2" border="0"> +<tr bgcolor="#a2c511"> <th valign="top">Option <th valign="top">Meaning +<tr bgcolor="#f0f0f0"> +<td valign="top">-o <em>file</em> +<td valign="top">Write output to <em>file</em> rather than to stdout. +<tr bgcolor="#d0d0d0"> +<td valign="top">-f +<td valign="top">Force the generation of an #include statement in the +output. This is the default for files whose name matches the <a href="qregexp.html#regular-expression">regular expression</a> \.[hH][^.]* (i.e. the extension starts with H or h). This +option is only useful if you have header files that do not follow the +standard naming conventions. +<tr bgcolor="#f0f0f0"> +<td valign="top">-i +<td valign="top">Do not generate an #include statement in the output. +This may be used to run the moc on on a C++ file containing one or +more class declarations. You should then #include the meta object +code in the .cpp +file. If both -i and -f are present, the last one wins. +<tr bgcolor="#d0d0d0"> +<td valign="top">-nw +<td valign="top">Do not generate any warnings. Not recommended. +<tr bgcolor="#f0f0f0"> +<td valign="top">-ldbg +<td valign="top">Write a flood of lex debug information to stdout. +<tr bgcolor="#d0d0d0"> +<td valign="top">-p <em>path</em> +<td valign="top">Makes the moc prepend <em>path</em>/ to +the file name in the generated #include statement (if one is +generated). +<tr bgcolor="#f0f0f0"> +<td valign="top">-q <em>path</em> +<td valign="top">Makes the moc prepend <em>path</em>/ to +the file name of qt #include files in the generated code. +</table></center> +<p> You can explicitly tell the moc not to parse parts of a header +file. It recognizes any C++ comment (//) that contains the substrings +MOC_SKIP_BEGIN or MOC_SKIP_END. They work as you would expect and you +can have several levels of them. The net result as seen by the moc is +as if you had removed all lines between a MOC_SKIP_BEGIN and a +MOC_SKIP_END. +<p> <h2> Diagnostics +</h2> +<a name="4"></a><p> The moc will warn you about a number of dangerous or illegal +constructs in the Q_OBJECT class declarations. +<p> If you get linkage errors in the final building phase of your +program, saying that YourClass::className() is undefined or that +YourClass lacks a vtbl, something has been done wrong. Most often, +you have forgotten 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> +<a name="5"></a><p> The moc does not expand #include or #define, it simply skips any +preprocessor directives it encounters. This is regrettable, but is +not usually a problem in practice. +<p> The moc does not handle all of C++. The main problem is that class +templates cannot have signals or slots. Here is an example: +<p> <pre> + class SomeTemplate<int> : public <a href="qframe.html">QFrame</a> { + Q_OBJECT + ... + signals: + void bugInMocDetected( int ); + }; +</pre> + +<p> Less importantly, the following constructs are illegal. All of them +have alternatives which we think are usually better, so removing these +limitations is not a high priority for us. +<p> <h3> Multiple inheritance requires <a href="qobject.html">QObject</a> to be first +</h3> +<a name="5-1"></a><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 <a href="qobject.html">QObject</a>, public OtherClass { + ... + }; +</pre> + +<p> (This limitation is almost impossible to remove; since the moc does not expand +#include or #define, it cannot find out which one of the base classes +is a QObject.) +<p> <h3> Function pointers cannot be arguments to signals or slots +</h3> +<a name="5-2"></a><p> In most cases where you would consider using function pointers as +signal/slot arguments, we think inheritance is a better alternative. +Here is an example of illegal syntax: +<p> <pre> + class SomeClass : public <a href="qobject.html">QObject</a> { + Q_OBJECT + ... + public slots: + // illegal + void apply( void (*apply)(List *, void *), char * ); + }; +</pre> + +<p> You can work around this restriction like this: +<pre> + typedef void (*ApplyFunctionType)( List *, void * ); + + class SomeClass : public <a href="qobject.html">QObject</a> { + Q_OBJECT + ... + public slots: + void apply( ApplyFunctionType, char * ); + }; +</pre> + +<p> It may sometimes be even better to replace the function pointer with +inheritance and virtual functions, signals or slots. +<p> <h3> Friend declarations cannot be placed in signals or slots sections +</h3> +<a name="5-3"></a><p> Sometimes it will work, but in general, friend declarations cannot be +placed in signals or slots sections. Put them in the private, +protected or public sections instead. Here is an example of the +illegal syntax: +<p> <pre> + class SomeClass : public <a href="qobject.html">QObject</a> { + Q_OBJECT + ... + signals: + friend class ClassTemplate<char>; // WRONG + }; +</pre> + +<p> <h3> Signals and slots cannot be upgraded +</h3> +<a name="5-4"></a><p> The C++ feature of upgrading an inherited member function to +public status is not extended to cover signals and slots. Here is an +illegal example: +<p> <pre> + class Whatever : public <a href="qbuttongroup.html">QButtonGroup</a> { + ... + public slots: + <a href="qbuttongroup.html">QButtonGroup</a>::buttonPressed; // WRONG + ... + }; +</pre> + +<p> The QButtonGroup::buttonPressed() slot is protected. +<p> C++ quiz: What happens if you try to upgrade a protected member +function which is overloaded? +<ol type=1> +<li> All the functions are overloaded. +<li> That is not legal C++. +</ol> +<p> +<p> <h3> Type macros cannot be used for signal and slot parameters +</h3> +<a name="5-5"></a><p> Since the moc does not expand #define, type macros that take an argument +will not work in signals and slots. Here is an illegal example: +<p> <pre> + #ifdef ultrix + #define SIGNEDNESS(a) unsigned a + #else + #define SIGNEDNESS(a) a + #endif + + class Whatever : public <a href="qobject.html">QObject</a> { + ... + signals: + void someSignal( SIGNEDNESS(int) ); + ... + }; +</pre> + +<p> A #define without parameters will work as expected. +<p> <h3> Nested classes cannot be in the signals or slots sections nor have +signals or slots +</h3> +<a name="5-6"></a><p> Here's an example: +<p> <pre> + class A { + Q_OBJECT + public: + class B { + public slots: // WRONG + void b(); + ... + }; + signals: + class B { // WRONG + void b(); + ... + }: + }; +</pre> + +<p> <h3> Constructors cannot be used in signals or slots sections +</h3> +<a name="5-7"></a><p> It is a mystery to us why anyone would put a constructor in +either the signals or slots sections. You can't anyway (except +that it happens to work in some cases). Put them in private, +protected or public sections, where they belong. Here is an example +of the illegal syntax: +<p> <pre> + class SomeClass : public <a href="qobject.html">QObject</a> { + Q_OBJECT + public slots: + SomeClass( <a href="qobject.html">QObject</a> *parent, const char *name ) + : <a href="qobject.html">QObject</a>( parent, name ) { } // WRONG + ... + }; +</pre> + +<p> <h3> Properties need to be declared before the public section that +contains the respective get and set functions +</h3> +<a name="5-8"></a><p> Declaring the first property within or after the public section that +contains the type definition and the respective get and set functions +does not work as expected. The moc will complain that it can neither +find the functions nor resolve the type. Here is an example of the +illegal syntax: +<p> <pre> + class SomeClass : public <a href="qobject.html">QObject</a> { + Q_OBJECT + public: + ... + Q_PROPERTY( Priority priority READ priority WRITE setPriority ) // WRONG + Q_ENUMS( Priority ) // WRONG + enum Priority { High, Low, VeryHigh, VeryLow }; + void setPriority( Priority ); + Priority priority() const; + ... + }; +</pre> + +<p> Work around this limitation by declaring all properties at the +beginning of the class declaration, right after Q_OBJECT: +<p> <pre> + class SomeClass : public <a href="qobject.html">QObject</a> { + Q_OBJECT + Q_PROPERTY( Priority priority READ priority WRITE setPriority ) + Q_ENUMS( Priority ) + public: + ... + enum Priority { High, Low, VeryHigh, VeryLow }; + void setPriority( Priority ); + Priority priority() const; + ... + }; +</pre> + +<p> +<!-- eof --> +<p><address><hr><div align=center> +<table width=100% cellspacing=0 border=0><tr> +<td>Copyright © 2007 +<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a> +<td align=right><div align=right>Qt 3.3.8</div> +</table></div></address></body> +</html> |