From d796c9dd933ab96ec83b9a634feedd5d32e1ba3f Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 8 Nov 2011 12:31:36 -0600 Subject: Test conversion to TQt3 from Qt3 8c6fc1f8e35fd264dd01c582ca5e7549b32ab731 --- doc/html/moc.html | 452 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 doc/html/moc.html (limited to 'doc/html/moc.html') diff --git a/doc/html/moc.html b/doc/html/moc.html new file mode 100644 index 000000000..322c570e7 --- /dev/null +++ b/doc/html/moc.html @@ -0,0 +1,452 @@ + + + + + +Using the Meta Object Compiler + + + + + + + +
+ +Home + | +All Classes + | +Main Classes + | +Annotated + | +Grouped Classes + | +Functions +

Using the Meta Object Compiler

+ + + +

+

The Meta Object Compiler, moc among friends, is the program which +handles TQt's C++ extensions. +

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 qmake 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 Why doesn't TQt +use templates for signals and slots?. +

Usage +

+

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

+    class MyClass : public TQObject
+    {
+        Q_OBJECT
+    public:
+        MyClass( TQObject * parent=0, const char * name=0 );
+        ~MyClass();
+
+    signals:
+        void mySignal();
+
+    public slots:
+        void mySlot();
+
+    };
+
+ +

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 +property system. In this particular +case we declare a property of the enumeration type Priority that is +also called "priority" and has a get function priority() and a set +function setPriority(). +

+    class MyClass : public TQObject
+    {
+        Q_OBJECT
+        Q_PROPERTY( Priority priority READ priority WRITE setPriority )
+        Q_ENUMS( Priority )
+    public:
+        MyClass( TQObject * parent=0, const char * name=0 );
+        ~MyClass();
+
+        enum Priority { High, Low, VeryHigh, VeryLow };
+        void setPriority( Priority );
+        Priority priority() const;
+    };
+
+ +

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: +

+    class MyClass : public TQObject
+    {
+        Q_OBJECT
+        Q_CLASSINFO( "Author", "Oscar Peterson")
+        Q_CLASSINFO( "Status", "Active")
+    public:
+        MyClass( TQObject * parent=0, const char * name=0 );
+        ~MyClass();
+    };
+
+ +

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: +

+

Method A: The class declaration is found in a header +(.h) file +

If the class declaration above is found in the file +myclass.h, the moc output should be put in a file called +moc_myclass.cpp. This file should then be compiled as +usual, resulting in an object file moc_myclass.o (on Unix) +or 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. +

Method B: The class declaration is found in an implementation +(.cpp) file +

If the class declaration above is found in the file +myclass.cpp, the moc output should be put in a file called +myclass.moc. This file should be #included in the +implementation file, i.e. myclass.cpp should contain the +line +
+    #include "myclass.moc"
+
+ +at the end. This will cause the moc-generated code to be compiled and +linked together with the normal class definition in myclass.cpp, so +it is not necessary to compile and link it separately, as in Method A. +

+

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. +

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, make can take care of running moc when necessary and +handling the moc output. +

We recommend using Trolltech's free makefile generation tool, qmake, 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: +

+    moc_%.cpp: %.h
+            moc $< -o $@
+
+ +

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

+    moc_NAME.cpp: NAME.h
+            moc $< -o $@
+
+ +

You must also remember to add moc_NAME.cpp to your SOURCES +(substitute your favorite name) variable and moc_NAME.o or +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: +

+    NAME.o: NAME.moc
+
+    NAME.moc: NAME.cpp
+            moc -i $< -o $@
+
+ +

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

+    #include "NAME.moc"
+
+ +

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

Invoking moc +

+

Here are the command-line options supported by the moc: +

+ + + + + + + +
Option Meaning +
-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][^.]* (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. +
-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. +
-nw +Do not generate any warnings. Not recommended. +
-ldbg +Write a flood of lex debug information to stdout. +
-p path +Makes the moc prepend path/ to +the file name in the generated #include statement (if one is +generated). +
-q path +Makes the moc prepend path/ to +the file name of qt #include files in the generated code. +
+

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. +

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. +

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: +

+    class SomeTemplate<int> : public TQFrame {
+        Q_OBJECT
+        ...
+    signals:
+        void bugInMocDetected( int );
+    };
+
+ +

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. +

Multiple inheritance retquires TQObject to be first +

+

If you are using multiple inheritance, moc assumes that the first +inherited class is a subclass of TQObject. Also, be sure that only +the first inherited class is a TQObject. +

+    class SomeClass : public TQObject, public OtherClass {
+        ...
+    };
+
+ +

(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 TQObject.) +

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: +

+    class SomeClass : public TQObject {
+        Q_OBJECT
+        ...
+    public slots:
+        // illegal
+        void apply( void (*apply)(List *, void *), char * );
+    };
+
+ +

You can work around this restriction like this: +

+    typedef void (*ApplyFunctionType)( List *, void * );
+
+    class SomeClass : public TQObject {
+        Q_OBJECT
+        ...
+    public slots:
+        void apply( ApplyFunctionType, char * );
+    };
+
+ +

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

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: +

+    class SomeClass : public TQObject {
+        Q_OBJECT
+        ...
+    signals:
+        friend class ClassTemplate<char>; // WRONG
+    };
+
+ +

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 TQButtonGroup {
+        ...
+    public slots:
+        TQButtonGroup::buttonPressed; // WRONG
+        ...
+    };
+
+ +

The TQButtonGroup::buttonPressed() slot is protected. +

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

    +
  1. All the functions are overloaded. +
  2. That is not legal C++. +
+

+

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: +

+    #ifdef ultrix
+    #define SIGNEDNESS(a) unsigned a
+    #else
+    #define SIGNEDNESS(a) a
+    #endif
+
+    class Whatever : public TQObject {
+        ...
+    signals:
+        void someSignal( SIGNEDNESS(int) );
+        ...
+    };
+
+ +

A #define without parameters will work as expected. +

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:   // WRONG
+            void b();
+            ...
+        };
+    signals:
+        class B {       // WRONG
+            void b();
+            ...
+        }:
+    };
+
+ +

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: +

+    class SomeClass : public TQObject {
+        Q_OBJECT
+    public slots:
+        SomeClass( TQObject *parent, const char *name )
+            : TQObject( parent, name ) { } // WRONG
+        ...
+    };
+
+ +

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 TQObject {
+        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;
+        ...
+    };
+
+ +

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

+    class SomeClass : public TQObject {
+        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;
+        ...
+    };
+
+ +

+ +


+ +
Copyright © 2007 +TrolltechTrademarks +
TQt 3.3.8
+
+ -- cgit v1.2.1