diff options
Diffstat (limited to 'doc/moc.doc')
-rw-r--r-- | doc/moc.doc | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/doc/moc.doc b/doc/moc.doc new file mode 100644 index 000000000..daf8b0048 --- /dev/null +++ b/doc/moc.doc @@ -0,0 +1,513 @@ +/**************************************************************************** +** +** Moc usage, expanded from the manual page +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing retquirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +// Note: Text in this file must also be copied to the moc man page: +// src/moc/moc.1 + +/*! +\page moc.html + +\title Using the Meta Object Compiler + +\keyword moc + +The Meta Object Compiler, moc among friends, is the program which +handles Qt's \link metaobjects.html C++ extensions.\endlink + +The moc reads a C++ source file. If it finds one or more class +declarations that contain the Q_OBJECT macro, it produces another +C++ source file which contains the meta object code for the classes +that use the Q_OBJECT macro. Among other things, meta object code is +retquired for the signal/slot mechanism, runtime type information and +the dynamic property system. + +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). + +If you use \link qmake-manual.book qmake\endlink to create your +Makefiles, build rules will be included that call the moc when +retquired, so you will not need to use the moc directly. For more +background information on moc, see \link templates.html Why doesn't Qt +use templates for signals and slots?\endlink. + +\section1 Usage + +The moc is typically used with an input file containing class declarations +like this: + +\code + class MyClass : public QObject + { + Q_OBJECT + public: + MyClass( QObject * parent=0, const char * name=0 ); + ~MyClass(); + + signals: + void mySignal(); + + public slots: + void mySlot(); + + }; +\endcode + +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 +\link properties.html property system\endlink. In this particular +case we declare a property of the enumeration type \c Priority that is +also called "priority" and has a get function \c priority() and a set +function \c setPriority(). + +\code + class MyClass : public QObject + { + Q_OBJECT + Q_PROPERTY( Priority priority READ priority WRITE setPriority ) + Q_ENUMS( Priority ) + public: + MyClass( QObject * parent=0, const char * name=0 ); + ~MyClass(); + + enum Priority { High, Low, VeryHigh, VeryLow }; + void setPriority( Priority ); + Priority priority() const; + }; +\endcode + +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: + +\code + class MyClass : public QObject + { + Q_OBJECT + Q_CLASSINFO( "Author", "Oscar Peterson") + Q_CLASSINFO( "Status", "Active") + public: + MyClass( QObject * parent=0, const char * name=0 ); + ~MyClass(); + }; +\endcode + +The three concepts, signals and slots, properties and class +meta-data, can be combined. + +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: + +<dl> + +<dt><b>Method A: The class declaration is found in a header +(\e .h) file</b> + +<dd>If the class declaration above is found in the file +\e myclass.h, the moc output should be put in a file called +\e moc_myclass.cpp. This file should then be compiled as +usual, resulting in an object file \e moc_myclass.o (on Unix) +or \e moc_myclass.obj (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. + + +<dt><b>Method B: The class declaration is found in an implementation +(\e .cpp) file</b> + +<dd>If the class declaration above is found in the file +\e myclass.cpp, the moc output should be put in a file called +\e myclass.moc. This file should be #included in the +implementation file, i.e. \e myclass.cpp should contain the +line +\code + #include "myclass.moc" +\endcode +at the end. This will cause the moc-generated code to be compiled and +linked together with the normal class definition in \e myclass.cpp, so +it is not necessary to compile and link it separately, as in Method A. + +</dl> + +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. + + +\section1 Automating moc Usage with Makefiles + +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, \e make can take care of running moc when necessary and +handling the moc output. + +We recommend using Trolltech's free makefile generation tool, \link +qmake-manual.book qmake\endlink, 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. + +If you want to create your Makefiles yourself, here are some tips on +how to include moc handling. + +For Q_OBJECT class declarations in header files, here is a useful +makefile rule if you only use GNU make: + +\code + moc_%.cpp: %.h + moc $< -o $@ +\endcode + +If you want to write portably, you can use individual rules with the +following form: + +\code + moc_NAME.cpp: NAME.h + moc $< -o $@ +\endcode + +You must also remember to add \e moc_NAME.cpp to your SOURCES +(substitute your favorite name) variable and \e moc_NAME.o or +\e moc_NAME.obj to your OBJECTS variable. + +(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.) + +For Q_OBJECT class declarations in implementation (.cpp) files, we +suggest a makefile rule like this: + +\code + NAME.o: NAME.moc + + NAME.moc: NAME.cpp + moc -i $< -o $@ +\endcode + +This guarantees that make will run the moc before it compiles +\e NAME.cpp. You can then put + +\code + #include "NAME.moc" +\endcode + +at the end of \e NAME.cpp, where all the classes declared in +that file are fully known. + + +\section1 Invoking moc + +Here are the command-line options supported by the moc: + +\table +\header \i Option \i Meaning +\row +\i -o \e file +\i Write output to \e file rather than to stdout. +\row +\i -f +\i Force the generation of an #include statement in the +output. This is the default for files whose name matches the regular +expression \.[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. +\row +\i -i +\i 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. +\row +\i -nw +\i Do not generate any warnings. Not recommended. +\row +\i -ldbg +\i Write a flood of lex debug information to stdout. +\row +\i -p \e path +\i Makes the moc prepend \e {path}/ to +the file name in the generated #include statement (if one is +generated). +\row +\i -q \e path +\i Makes the moc prepend \e {path}/ to +the file name of qt #include files in the generated code. +\endtable + +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. + + +\section1 Diagnostics + +The moc will warn you about a number of dangerous or illegal +constructs in the Q_OBJECT class declarations. + +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. + + +\section1 Limitations + +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. + +The moc does not handle all of C++. The main problem is that class +templates cannot have signals or slots. Here is an example: + +\code + class SomeTemplate<int> : public QFrame { + Q_OBJECT + ... + signals: + void bugInMocDetected( int ); + }; +\endcode + +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. + +\section2 Multiple inheritance retquires QObject to be first + +If you are using multiple inheritance, moc assumes that the \e first +inherited class is a subclass of QObject. Also, be sure that \e only +the first inherited class is a QObject. + +\code + class SomeClass : public QObject, public OtherClass { + ... + }; +\endcode + +(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.) + +\section2 Function pointers cannot be arguments to signals or slots + +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: + +\code + class SomeClass : public QObject { + Q_OBJECT + ... + public slots: + // illegal + void apply( void (*apply)(List *, void *), char * ); + }; +\endcode + +You can work around this restriction like this: +\code + typedef void (*ApplyFunctionType)( List *, void * ); + + class SomeClass : public QObject { + Q_OBJECT + ... + public slots: + void apply( ApplyFunctionType, char * ); + }; +\endcode + +It may sometimes be even better to replace the function pointer with +inheritance and virtual functions, signals or slots. + +\section2 Friend declarations cannot be placed in signals or slots sections + +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: + +\code + class SomeClass : public QObject { + Q_OBJECT + ... + signals: + friend class ClassTemplate<char>; // WRONG + }; +\endcode + +\section2 Signals and slots cannot be upgraded + +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: + +\code + class Whatever : public QButtonGroup { + ... + public slots: + QButtonGroup::buttonPressed; // WRONG + ... + }; +\endcode + +The QButtonGroup::buttonPressed() slot is protected. + +C++ tquiz: What happens if you try to upgrade a protected member +function which is overloaded? +\list 1 +\i All the functions are overloaded. +\i That is not legal C++. +\endlist + +\omit +C++ ARM, section r.11.3 +\endomit + +\section2 Type macros cannot be used for signal and slot parameters + +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: + +\code + #ifdef ultrix + #define SIGNEDNESS(a) unsigned a + #else + #define SIGNEDNESS(a) a + #endif + + class Whatever : public QObject { + ... + signals: + void someSignal( SIGNEDNESS(int) ); + ... + }; +\endcode + +A #define without parameters will work as expected. + +\section2 Nested classes cannot be in the signals or slots sections nor have +signals or slots + +Here's an example: + +\code + class A { + Q_OBJECT + public: + class B { + public slots: // WRONG + void b(); + ... + }; + signals: + class B { // WRONG + void b(); + ... + }: + }; +\endcode + +\section2 Constructors cannot be used in signals or slots sections + +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: + +\code + class SomeClass : public QObject { + Q_OBJECT + public slots: + SomeClass( QObject *parent, const char *name ) + : QObject( parent, name ) { } // WRONG + ... + }; +\endcode + +\section2 Properties need to be declared before the public section that +contains the respective get and set functions + +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: + +\code + class SomeClass : public QObject { + 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; + ... + }; +\endcode + +Work around this limitation by declaring all properties at the +beginning of the class declaration, right after Q_OBJECT: + +\code + class SomeClass : public QObject { + 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; + ... + }; +\endcode + +*/ |