moc - generate Qt meta object support code


SYNOPSIS

       moc  [-o  file] [-i] [-f] [-k] [-ldbg] [-nw] [-p path] [-q
       path] file


DESCRIPTION

       This page documents the Meta Object Compiler  for  the  Qt
       GUI  application  framework. The moc reads one or more C++
       class declarations from a C++ header or  source  file  and
       generates  one  C++  source  file  containing  meta object
       information for the classes. 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' source file).

       In brief, the meta object system is a structure used by Qt
       (see http://doc.trolltech.com) for  component  programming
       and  run  time  type  information.  It adds properties and
       inheritance information to (some) classes and  provides  a
       new type of communication between those instances of those
       classes, signal-slot connections.


OPTIONS

       -o file
              Write output to file rather than to stdout.

       -f     Force the generation of an  #include  statement  in
              the  output.   This  is the default for files whose
              name matches the regular expression .[hH][^.]* (ie.
              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.

       -i     Do  not  generate  an  #include  statement  in  the
              output.  This may be used to run moc on a C++  file
              containing  one  or  more  class  declarations. You
              should then #include the meta object  code  in  the
              .cpp file (see USAGE below).  If both -f and -i are
              present, the last one wins.

       -nw    Do not generate any warnings. Discouraged.

       -ldbg  Write a flood of lex debug information on stdout.

       -p path
              Makes moc prepend path/ to the  file  name  in  the
              generated #include statement (if one is generated).

       -q path
              Makes moc prepend path/ to  the  file  name  of  qt
              #include files in the generated code.

       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


USAGE

       moc is almost always invoked by make(1), not by hand.

       moc  is typically used with an input file containing class
       declarations like this skeleton:

           class YourClass: public QObject {
               Q_OBJECT
               Q_PROPERTY( ... )
               Q_CLASSINFO( ... )

           public:
               YourClass( QObject * parent=0, const char * name=0 );
               ~YourClass();

           signals:

           public slots:

           };

       Here is a useful makefile rule if you only use GNU make:

           m%.cpp: %.h
                   moc $< -o $@

       If you want to write  portably,  you  can  use  individual
       rules of the following form:

           mNAME.cpp: NAME.h
                   moc $< -o $@

       You  must  also  remember to add mNAME.cpp to your SOURCES
       (substitute your favorite name) variable  and  mNAME.o  to
       your OBJECTS variable.

       (While  we  prefer  to name our C++ source files .cpp, the
       moc doesn't know that, so you can use .C, .cc,  .CC,  .cxx
       or even .c++ if you prefer.)

       If  you have class declarations in C++ files, we recommend
       that you use a makefile rule like this:

           NAME.o: mNAME.cpp

           mNAME.cpp: NAME.cpp


       This guarantees that make(1) will run the  moc  before  it
       compiles NAME.cpp.  You can then put

           #include "nNAME.cpp"

       at  the end of NAME.cpp, where all the classes declared in
       that file are fully known.


DIAGNOSTICS

       Sometimes  you  may  get  linkage  errors,   saying   that
       YourClass::className()  is  undefined  or  that  YourClass
       lacks a vtbl.  Those errors happen  most  often  when  you
       forget  to  compile  the moc-generated C++ code or include
       that object file in the link command.

       The moc will warn you  about  a  number  of  dangerous  or
       illegal constructs.


BUGS

       The  moc  does  not  expand #include or #define, it simply
       skips any preprocessor directives it encounters.  This  is
       regrettable, but is normally not a problem in practice.

       The  moc  does not handle all of C++.  The main problem is
       that class templates cannot have signals or  slots.   This
       is an important bug.  Here is an example:

           class SomeTemplate<int>: public QFrame {
               Q_OBJECT
               [...]
           signals:
               void bugInMocDetected( int );
           };

       Less  importantly,  the  following constructs are illegal.
       All of them have have  alternatives  which  we  think  are
       usually  better,  so  removing  these limitations is not a
       high priority for us.

   Multiple inheritance requires QObject to be first.
       If you are using multiple inheritance,  moc  assumes  that
       the first inherited class is a subclass of QObject.  Also,
       be sure that only the first inherited class is a  QObject.

           class SomeClass: public QObject, public OtherClass {
               [...]
           };

       This  bug  is almost impossible to fix; since the moc does
       not expand #include or #define, it cannot find  out  which
       one of the base classes is a QObject.

       You  can not use virtual inheritance in the QObject branch
       of the inheritance tree. The following example  shows  one
       wrong and one correct class declaration:

           class Wrong: virtual public QObject, virtual public Other {
               [...]
           };

           class Right: public QObject, virtual public Other {
               [...]
           };

   Virtual   functions   cannot  be  slots  when  using  multiple
       inheritance
       This problem occurs if you are using multiple inheritance.
       If  you  reimplement a virtual function as a slot and that
       function was originally declared in a class that does  not
       inherit  QObject,  your  program  may  crash when a signal
       triggers  the  slot.   (This  only   happens   with   some
       compilers.)

       The following example shows one wrong and two correct slot
       definitions.

           class BaseClass {
               [...]
               virtual void setValue( int );
           };

           class SubClass: public QObject, public BaseClass {
               [...]
           public slots:
               void setValue( int ); // illegal
               void slotSetValue( int i ) { setValue(i); } // ok
               void setName( const char* ); // ok
           };

       (For those interested in C++ internals: The cause of  this
       problem  is  that  a  slot  is internally represented as a
       function pointer, and invoked on a QObject pointer. )

   Function pointers can not be arguments to signals or slots.
       In most cases where you  would  consider  that,  we  think
       inheritance  is  a better alternative.  Here is an example
       of illegal syntax:

           class someClass: public QObject {
               Q_OBJECT
               [...]
           public slots:
               void apply(void (*ApplyFunction)(QList*, void*)); // illegal
           };


           typedef void (*ApplyFunctionType)(QList*, void*);

           class someClass: public QObject {
               Q_OBJECT
               [...]
           public slots:
               void apply( ApplyFunctionType );
           };

       (It may sometimes be even better to replace  the  function
       pointer with inheritance and virtual functions, signals or
       slots.)

   Friend declarations can not be  placed  in  signals  or  slots
       sections
       Sometimes   it   will   work,   but   in  general,  friend
       declarations  can  not  be  placed  in  signals  or  slots
       sections.   Put them in the good old private, protected or
       public sections  instead.   Here  is  an  example  of  the
       illegal syntax:

           class someClass: public QObject {
               Q_OBJECT
               [...]
           signals:
               friend class ClassTemplate<char>; // illegal
           };

   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:

           class Whatever: public QButtonGroup {
               [...]
           public slots:
               void QButtonGroup::buttonPressed(); // illegal
           };

       The QButtonGroup::buttonPressed() slot is protected.

       C++  quiz:  What happens if you try to upgrade a protected
       member function which is overloaded?

              - All the functions are upgraded.

              - That is not legal C++.

   Type macros can not be used for signal and slot arguments
       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:

           #define SIGNEDNESS(a) unsigned a
           #else
           #define SIGNEDNESS(a) a
           #endif
           class Whatever: public QObject {
           [...]
           signals:
               void someSignal( SIGNEDNESS(a) ); // illegal
           };

       A #define without arguments works.

   Nested classes cannot be in the signals or slots sections  nor
       have signals or slots
       Here's an example:

           class A {
               Q_OBJECT
           public:
               class B {
               public slots: // illegal
                   void b();
               [....]
               };
           signals:
               class B {  // illegal
                   void b();
                [....]
               }:
           };

   Constructors can not be used in signals or slots sections
       It  is  a mystery to me why anyone would put a constructor
       on either the signals or slots  sections.   You  can  not,
       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:

           class SomeClass: public QObject {
               Q_OBJECT
           public slots:
               SomeClass( QObject *parent, const char *name )
                   : QObject( parent, name ) {} // illegal
               [...]
           };

   Signals and slots may not have default arguments
       Since  signal->slot  binding  occurs  at  run-time,  it is
       conceptually difficult to use  default  parameters,  which
       are a compile-time phenomenon.  This will fail:

           class SomeClass: public QObject {

           public slots:
               void someSlot(int x=100); // illegal
           };

   Signals and slots may not have template arguments
       Declaring  signals and slots with template-type parameters
       will not work as expected, even though the  moc  will  not
       complain.  Connecting  the  signal  to  the  slot  in  the
       following example, the slot will not get executed when the
       signal is emitted:

           public slots:
               void MyWidget::setLocation(pair<int,int> location); // illegal
               [...]
           public signals:
               void MyObject::moved(pair<int,int> location); // illegal

       However, you can work around this limitation by explicitly
       typedef'ing the parameter types, like this:

           typedef pair<int,int> IntPair;

           public slots:
               void MyWidget::setLocation(IntPair location);
               [...]
           public signals:
               void MyObject::moved(IntPair location);

       This will work as expected.

   Namespace of parent class must be specified even if it is  the
       same as that of the subclass
       In  the  following  example,  classes  x::A  and  x::B are
       defined:

           namespace x {
               class A : public QObject {
                   Q_OBJECT

               public:
                   ...
               };
           }

           namespace x {
               class B : public A {
                   Q_OBJECT

               public:
                   ...
               };
           }


               class B : public A {

       line. You have either to write

               class B : public x::A {

       or define classes A and B in the same namespace block.

       This limitation will disappear with Qt 3.0.

   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:

           class SomeClass: public QObject {
               Q_OBJECT
           public:
               [...]
               // illegal
               Q_PROPERTY( Priority priority READ priority WRITE setPriority )
               Q_ENUMS( Priority )
               enum Priority { High, Low, VeryHigh, VeryLow };
               void setPriority( Priority );
               Priority priority() const;
               [...]
           };

       Work around this limitation by declaring all properties at
       the  beginning  of  the  class  declaration,  right  after
       Q_OBJECT:

           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;
               [...]
           };


SEE ALSO

       http://www.trolltech.com/ and C++ ARM, section r.11.3 (for



AUTHOR

       Eirik Eng, Trolltech <eiriken@trolltech.com>


Man(1) output converted with man2html