/**************************************************************************** ** ** Explanation of the Qt object model ** ** Copyright (C) 2000-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 requirements 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. ** **********************************************************************/ /*! \page object.html \title Qt Object Model The standard C++ Object Model provides very efficient runtime support for the object paradigm. But the C++ Object Model's static nature is inflexibile in certain problem domains. Graphical User Interface programming is a domain that requires both runtime efficiency and a high level of flexibility. Qt provides this, by combining the speed of C++ with the flexibility of the Qt Object Model. Qt adds these features to C++: \list \i a very powerful mechanism for seamless object communication called \link signalsandslots.html signals and slots \endlink; \i queryable and designable \link properties.html object properties \endlink; \i powerful \link eventsandfilters.html events and event filters \endlink, \i contextual \link i18n.html string translation for internationalization \endlink; \i sophisticated interval driven \link timers.html timers \endlink that make it possible to elegantly integrate many tasks in an event-driven GUI; \i hierarchical and queryable \link objecttrees.html object trees \endlink that organize object ownership in a natural way; \i guarded pointers, \l QGuardedPtr, that are automatically set to 0 when the referenced object is destroyed, unlike normal C++ pointers which become "dangling pointers" when their objects are destroyed. \endlist Many of these Qt features are implemented with standard C++ techniques, based on inheritance from \l QObject. Others, like the object communication mechanism and the dynamic property system, require the \link metaobjects.html Meta Object System \endlink provided by Qt's own \link moc.html Meta Object Compiler (moc) \endlink. The Meta Object System is a C++ extension that makes the language better suited to true component GUI programming. Although templates can be used to extend C++, the Meta Object System provides benefits using standard C++ that cannot be achieved with templates; see \link templates.html Why doesn't Qt use templates for signals and slots? \endlink. */ /*! \page timers.html \title Timers \l QObject, the base class of all Qt objects, provides the basic timer support in Qt. With \l QObject::startTimer(), you start a timer with an \e interval in milliseconds as argument. The function returns a unique integer timer id. The timer will now "fire" every \e interval milliseconds, until you explicitly call \l QObject::killTimer() with the timer id. For this mechanism to work, the application must run in an event loop. You start an event loop with \l QApplication::exec(). When a timer fires, the application sends a QTimerEvent, and the flow of control leaves the event loop until the timer event is processed. This implies that a timer cannot fire while your application is busy doing something else. In other words: the accuracy of timers depends on the granularity of your application. There is practically no upper limit for the interval value (more than one year is possible). The accuracy depends on the underlying operating system. Windows 95/98 has 55 millisecond (18.2 times per second) accuracy; other systems that we have tested (UNIX X11 and Windows NT) can handle 1 millisecond intervals. The main API for the timer functionality is \l QTimer. That class provides regular timers that emit a signal when the timer fires, and inherits \l QObject so that it fits well into the ownership structure of most GUI programs. The normal way of using it is like this: \code QTimer * counter = new QTimer( this ); connect( counter, SIGNAL(timeout()), this, SLOT(updateCaption()) ); counter->start( 1000 ); \endcode The counter timer is made into a child of this widget, so that when this widget is deleted, the timer is deleted too. Next, its timeout signal is connected to the slot that will do the work, and finally it's started. QTimer also provides a simple one-shot timer API. \l QButton uses this to show the button being pressed down and then (0.1 seconds later) be released when the keyboard is used to "press" a button, for example: \code QTimer::singleShot( 100, this, SLOT(animateTimeout()) ); \endcode 0.1 seconds after this line of code is executed, the same button's animateTimeout() slot is called. Here is an outline of a slightly longer example that combines object communication via signals and slots with a QTimer object. It demonstrates how to use timers to perform intensive calculations in a single-threaded application without blocking the user interface. \code // The Mandelbrot class uses a QTimer to calculate the mandelbrot // set one scanline at a time without blocking the CPU. It // inherits QObject to use signals and slots. Calling start() // starts the calculation. The done() signal is emitted when it // has finished. Note that this example is not complete, just an // outline. class Mandelbrot : public QObject { Q_OBJECT // required for signals/slots public: Mandelbrot( QObject *parent=0, const char *name ); ... public slots: void start(); signals: void done(); private slots: void calculate(); private: QTimer timer; ... }; // // Constructs and initializes a Mandelbrot object. // Mandelbrot::Mandelbrot( QObject *parent=0, const char *name ) : QObject( parent, name ) { connect( &timer, SIGNAL(timeout()), SLOT(calculate()) ); ... } // // Starts the calculation task. The internal calculate() slot // will be activated every 10 milliseconds. // void Mandelbrot::start() { if ( !timer.isActive() ) // not already running timer.start( 10 ); // timeout every 10 ms } // // Calculates one scanline at a time. // Emits the done() signal when finished. // void Mandelbrot::calculate() { ... // perform the calculation for a scanline if ( finished ) { // no more scanlines timer.stop(); emit done(); } } \endcode */ /*! \page properties.html \title Properties Qt provides a sophisticated property system similar to those supplied by some compiler vendors. However, as a compiler- and platform-independent library, Qt cannot rely on non-standard compiler features like \c __property or \c [property]. Our solution works with \e any standard C++ compiler on every platform we support. It's based on the meta-object system that also provides object communication through \link signalsandslots.html signals and slots\endlink. The \c Q_PROPERTY macro in a class declaration declares a property. Properties can only be declared in classes that inherit \l QObject. A second macro, \c Q_OVERRIDE, can be used to override some aspects of an inherited property in a subclass. (See \link #override Q_OVERRIDE\endlink.) To the outer world, a property appears to be similar to a data member. But properties have several features that distinguish them from ordinary data members: \list \i A read function. This always exists. \i A write function. This is optional: read-only properties like \l QWidget::isDesktop() do not have one. \i An attribute "stored" that indicates persistence. Most properties are stored, but a few virtual properties are not. For example, \l QWidget::minimumWidth() isn't stored, since it's just a view of \l QWidget::minimumSize(), and has no data of its own. \i A reset function to set a property back to its context specific default value. This is very rare, but for example, \l QWidget::font() needs this, since no call to \l QWidget::setFont() can mean 'reset to the context specific font'. \i An attribute "designable" that indicates whether it makes sense to make the property available in a GUI builder (e.g. \link designer-manual.book Qt Designer\endlink). For most properties this makes sense, but not for all, e.g. \l QButton::isDown(). The user can press buttons, and the application programmer can make the program press its own buttons, but a GUI design tool can't press buttons. \endlist The read, write, and reset functions must be public member functions from the class in which the property is defined. Properties can be read and written through generic functions in QObject without knowing anything about the class in use. These two function calls are equivalent: \code // QButton *b and QObject *o point to the same button b->setDown( TRUE ); o->setProperty( "down", TRUE ); \endcode Equivalent, that is, except that the first is faster, and provides much better diagnostics at compile time. When practical, the first is better. However, since you can get a list of all available properties for any QObject through its \l QMetaObject, \l QObject::setProperty() can give you control over classes that weren't available at compile time. As well as QObject::setProperty(), there is a corresponding \l QObject::property() function. \l QMetaObject::propertyNames() returns the names of all available properties. \l QMetaObject::property() returns the property data for a named property: a \l QMetaProperty object. Here's a simple example that shows the most important property functions in use: \code class MyClass : public QObject { Q_OBJECT public: MyClass( QObject * parent=0, const char * name=0 ); ~MyClass(); enum Priority { High, Low, VeryHigh, VeryLow }; void setPriority( Priority ); Priority priority() const; }; \endcode The class has a property "priority" that is not yet known to the meta object system. In order to make the property known, you must declare it with the \c Q_PROPERTY macro. The syntax is as follows: \code Q_PROPERTY( type name READ getFunction [WRITE setFunction] [RESET resetFunction] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] ) \endcode For the declaration to be valid, the get function must be const and to return either the type itself, a pointer to it, or a reference to it. The optional write function must return void and must take exactly one argument, either the type itself, a pointer or a const reference to it. The meta object compiler enforces this. The type of a property can be any \l QVariant supported type or an enumeration type declared in the class itself. Since \c MyClass uses the enumeration type \c Priority for the property, this type must be registered with the property system as well. There are two exceptions to the above: The type of a property can also be either \link QValueList QValueList\\endlink or \link QMap QMap\\endlink. In these cases the type must be specified as \c QValueList or as \c QMap (i.e. without their template parameters). It is possible to set a value by name, like this: \code obj->setProperty( "priority", "VeryHigh" ); \endcode In the case of \c QValueList and \c QMap properties the value passes is a QVariant whose value is the entire list or map. Enumeration types are registered with the \c Q_ENUMS macro. Here's the final class declaration including the property related declarations: \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 Another similar macro is \c Q_SETS. Like \c Q_ENUMS, it registers an enumeration type but marks it in addition as a "set", i.e. the enumeration values can be OR-ed together. An I/O class might have enumeration values "Read" and "Write" and accept "Read|Write": such an enum is best handled with \c Q_SETS, rather than \c Q_ENUMS. The remaining keywords in the \c Q_PROPERTY section are \c RESET, \c DESIGNABLE, \c SCRIPTABLE and \c STORED. \c RESET names a function that will set the property to its default state (which may have changed since initialization). The function must return void and take no arguments. \c DESIGNABLE declares whether this property is suitable for modification by a GUI design tool. The default is \c TRUE for writable properties; otherwise \c FALSE. Instead of \c TRUE or \c FALSE, you can specify a boolean member function. \c SCRIPTABLE declares whether this property is suited for access by a scripting engine. The default is \c TRUE. Instead of \c TRUE or \c FALSE, you can specify a boolean member function. \c STORED declares whether the property's value must be remembered when storing an object's state. Stored makes only sense for writable properties. The default value is \c TRUE. Technically superfluous properties (like QPoint pos if QRect geometry is already a property) define this to be \c FALSE. Connected to the property system is an additional macro, "Q_CLASSINFO", that can be used to attach additional name/value-pairs to a class' meta object, for example: \code Q_CLASSINFO( "Version", "3.0.0" ) \endcode Like other meta data, class information is accessible at runtime through the meta object, see \l QMetaObject::classInfo() for details. \target override \section1 Q_OVERRIDE When you inherit a QObject subclass you may wish to override some aspects of some of the class's properties. For example, in QWidget we have the autoMask property defined like this: \code Q_PROPERTY( bool autoMask READ autoMask WRITE setAutoMask DESIGNABLE false SCRIPTABLE false ) \endcode But we need to make the auto mask property designable in some QWidget subclasses. Similarly some classes will need this property to be scriptable (e.g. for QSA). This is achieved by overriding these features of the property in a subclass. In QCheckBox, for example, we achieve this using the following code: \code Q_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true ) \endcode Another example is QToolButton. By default QToolButton has a read-only "toggleButton" property, because that's what it inherits from QButton: \code Q_PROPERTY( bool toggleButton READ isToggleButton ) \endcode But we want to make our tool buttons able to be toggled, so we write a WRITE function in QToolButton, and use the following property override to make it acessible: \code Q_OVERRIDE( bool toggleButton WRITE setToggleButton ) \endcode The result is read-write (and scriptable and designable, since we now have a WRITE function) boolean property "toggleButton" for tool buttons. */ /*! \page eventsandfilters.html \title Events and Event Filters In Qt, an event is an object that inherits \l QEvent. Events are delivered to objects that inherit \l QObject through calling \l QObject::event(). Event delivery means that an event has occurred, the QEvent indicates precisely what, and the QObject needs to respond. Most events are specific to \l QWidget and its subclasses, but there are important events that aren't related to graphics, for example, socket activation, which is the event used by \l QSocketNotifier for its work. Some events come from the window system, e.g. \l QMouseEvent, some from other sources, e.g. \l QTimerEvent, and some come from the application program. Qt is symmetric, as usual, so you can send events in exactly the same ways as Qt's own event loop does. Most events types have special classes, most commonly \l QResizeEvent, \l QPaintEvent, \l QMouseEvent, \l QKeyEvent and \l QCloseEvent. There are many others, perhaps forty or so, but most are rather odd. Each class subclasses QEvent and adds event-specific functions; see, for example, \l QResizeEvent. In the case of QResizeEvent, \l QResizeEvent::size() and \l QResizeEvent::oldSize() are added. Some classes support more than one event type. \l QMouseEvent supports mouse moves, presses, shift-presses, drags, clicks, right-presses, etc. Since programs need to react in varied and complex ways, Qt's event delivery mechanisms are flexible. The documentation for \l QApplication::notify() concisely tells the whole story, here we will explain enough for 99% of applications. The normal way for an event to be delivered is by calling a virtual function. For example, \l QPaintEvent is delivered by calling \l QWidget::paintEvent(). This virtual function is responsible for reacting appropriately, normally by repainting the widget. If you do not perform all the necessary work in your implementation of the virtual function, you may need to call the base class's implementation; for example: \code MyTable::contentsMouseMoveEvent( QMouseEvent *me ) { // my implementation QTable::contentsMouseMoveEvent( me ); // hand it on } \endcode If you want to replace the base class's function then you must implement everything yourself; but if you only want to extend the base class's functionality, then you implement what you want and then call the base class. Occasionally there isn't such an event-specific function, or the event-specific function isn't sufficient. The most common example is tab key presses. Normally, those are interpreted by QWidget to move the keyboard focus, but a few widgets need the tab key for themselves. These objects can reimplement \l QObject::event(), the general event handler, and either do their event handling before or after the usual handling, or replace it completely. A very unusual widget that both interprets tab and has an application-specific custom event might contain: \code bool MyClass:event( QEvent *evt ) { if ( evt->type() == QEvent::KeyPress ) { QKeyEvent *ke = (QKeyEvent *)evt; if ( ke->key() == Key_Tab ) { // special tab handling here ke->accept(); return TRUE; } } else if ( evt->type() >= QEvent::User ) { QCustomEvent *ce = (QCustomEvent*) evt; // custom event handling here return TRUE; } return QWidget::event( evt ); } \endcode More commonly, an object needs to look at another's events. Qt supports this using \l QObject::installEventFilter() (and the corresponding remove). For example, dialogs commonly want to filter key presses for some widgets, e.g. to modify Return-key handling. An event filter gets to process events before the target object does. The filter's \l QObject::eventFilter() implementation is called, and can accept or reject the filter, and allow or deny further processing of the event. If all the event filters allow further processing of an event, the event is sent to the target object itself. If one of them stops processing, the target and any later event filters don't get to see the event at all. It's also possible to filter \e all events for the entire application, by installing an event filter on \l QApplication. This is what \l QToolTip does in order to see \e all the mouse and keyboard activity. This is very powerful, but it also slows down event delivery of every single event in the entire application, so it's best avoided. The global event filters are called before the object-specific filters. Finally, many applications want to create and send their own events. Creating an event of a built-in type is very simple: create an object of the relevant type, and then call \l QApplication::sendEvent() or \l QApplication::postEvent(). sendEvent() processes the event immediately - when sendEvent() returns, (the event filters and) the object have already processed the event. For many event classes there is a function called isAccepted() that tells you whether the event was accepted or rejected by the last handler that was called. postEvent() posts the event on a queue for later dispatch. The next time Qt's main event loop runs, it dispatches all posted events, with some optimization. For example, if there are several resize events, they are are compacted into one. The same applies to paint events: \l QWidget::update() calls postEvent(), which minimizes flickering and increases speed by avoiding multiple repaints. postEvent() is also often used during object initialization, since the posted event will typically be dispatched very soon after the initialization of the object is complete. To create events of a custom type, you need to define an event number, which must be greater than \c QEvent::User, and probably you also need to subclass \l QCustomEvent in order to pass characteristics about your custom event. See the documentation to \l QCustomEvent for details. */ /*! \page objecttrees.html \title Object Trees and Object Ownership \link QObject QObjects\endlink organize themselves in object trees. When you create a QObject with another object as parent, it's added to the parent's \link QObject::children() children() \endlink list, and is deleted when the parent is. It turns out that this approach fits the needs of GUI objects very well. For example, a \l QAccel (keyboard accelerator) is a child of the relevant window, so when the user closes that window, the accelerator is deleted too. The static function \l QObject::objectTrees() provides access to all the root objects that currently exist. \l QWidget, the base class of everything that appears on the screen, extends the parent-child relationship. A child normally also becomes a child widget, i.e. it is displayed in its parent's coordinate system and is graphically clipped by its parent's boundaries. For example, when the an application deletes a message box after it has been closed, the message box's buttons and label are also deleted, just as we'd want, because the buttons and label are children of the message box. You can also delete child objects yourself, and they will remove themselves from their parents. For example, when the user removes a toolbar it may lead to the application deleting one of its \l QToolBar objects, in which case the tool bar's \l QMainWindow parent would detect the change and reconfigure its screen space accordingly. The debugging functions \l QObject::dumpObjectTree() and \l QObject::dumpObjectInfo() are often useful when an application looks or acts strangely. */ /*! \page templates.html \title Why doesn't Qt use templates for signals and slots? A simple answer is that when Qt was designed, it was not possible to fully exploit the template mechanism in multi-platform applications due to the inadequacies of various compilers. Even today, many widely used C++ compilers have problems with advanced templates. For example, you cannot safely rely on partial template instantiation, which is essential for some non-trivial problem domains. Thus Qt's usage of templates has to be rather conservative. Keep in mind that Qt is a multi-platform toolkit, and progress on the Linux/g++ platform does not necessarily improve the situation elsewhere. Eventually those compilers with weak template implementations will improve. But even if all our users had access to a fully standards compliant modern C++ compiler with excellent template support, we would not abandon the string-based approach used by our meta object compiler. Here are five reasons why:

1. Syntax matters

Syntax isn't just sugar: the syntax we use to express our algorithms can significantly affect the readability and maintainability of our code. The syntax used for Qt's signals and slots has proved very successful in practice. The syntax is intuitive, simple to use and easy to read. People learning Qt find the syntax helps them understand and utilize the signals and slots concept -- despite its highly abstract and generic nature. Furthermore, declaring signals in class definitions ensures that the signals are protected in the sense of protected C++ member functions. This helps programmers get their design right from the very beginning, without even having to think about design patterns.

2. Precompilers are good

Qt's moc (Meta Object Compiler) provides a clean way to go beyond the compiled language's facilities. It does so by generating additional C++ code which can be compiled by any standard C++ compiler. The moc reads C++ source files. 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 those 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's source file). Typically moc is not called manually, but automatically by the build system, so it requires no additional effort by the programmer. There are other precompilers, for example, rpc and idl, that enable programs or objects to communicate over process or machine boundaries. The alternatives to precompilers are hacked compilers, proprietary languages or graphical programming tools with dialogs or wizards that generate obscure code. Rather than locking our customers into a proprietary C++ compiler or into a particular Integrated Development Environment, we enable them to use whatever tools they prefer. Instead of forcing programmers to add generated code into source repositories, we encourage them to add our tools to their build system: cleaner, safer and more in the spirit of UNIX.

3. Flexibility is king

C++ is a standarized, powerful and elaborate general-purpose language. It's the only language that is exploited on such a wide range of software projects, spanning every kind of application from entire operating systems, database servers and high end graphics applications to common desktop applications. One of the keys to C++'s success is its scalable language design that focuses on maximum performance and minimal memory consumption whilst still maintaining ANSI-C compatibility. For all these advantages, there are some downsides. For C++, the static object model is a clear disadvantage over the dynamic messaging approach of Objective C when it comes to component-based graphical user interface programming. What's good for a high end database server or an operating system isn't necessarily the right design choice for a GUI frontend. With moc, we have turned this disadvantage into an advantage, and added the flexibility required to meet the challenge of safe and efficient graphical user interface programming. Our approach goes far beyond anything you can do with templates. For example, we can have object properties. And we can have overloaded signals and slots, which feels natural when programming in a language where overloads are a key concept. Our signals add zero bytes to the size of a class instance, which means we can add new signals without breaking binary compatibility. Because we do not rely on excessive inlining as done with templates, we can keep the code size smaller. Adding new connections just expands to a simple function call rather than a complex template function. Another benefit is that we can explore an object's signals and slots at runtime. We can establish connections using type-safe call-by-name, without having to know the exact types of the objects we are connecting. This is impossible with a template based solution. This kind of runtime introspection opens up new possibilities, for example GUIs that are generated and connected from Qt Designer's XML ui files.

4. Calling performance is not everything

Qt's signals and slots implementation is not as fast as a template-based solution. While emitting a signal is approximately the cost of four ordinary function calls with common template implementations, Qt requires effort comparable to about ten function calls. This is not surprising since the Qt mechanism includes a generic marshaller, introspection and ultimately scriptability. It does not rely on excessive inlining and code expansion and it provides unmatched runtime safety. Qt's iterators are safe while those of faster template-based systems are not. Even during the process of emitting a signal to several receivers, those receivers can be deleted safely without your program crashing. Without this safety, your application would eventually crash with a difficult to debug free'd memory read or write error. Nonetheless, couldn't a template-based solution improve the performance of an application using signals and slots? While it is true that Qt adds a small overhead to the cost of calling a slot through a signal, the cost of the call is only a small proportion of the entire cost of a slot. Benchmarking against Qt's signals and slots system is typically done with empty slots. As soon as you do anything useful in your slots, for example a few simple string operations, the calling overhead becomes negligible. Qt's system is so optimized that anything that requires operator new or delete (for example, string operations or inserting/removing something from a template container) is significantly more expensive than emitting a signal. Aside: If you have a signals and slots connection in a tight inner loop of a performance critical task and you identify this connection as the bottleneck, think about using the standard listener-interface pattern rather than signals and slots. In cases where this occurs, you probably only require a 1:1 connection anyway. For example, if you have an object that downloads data from the network, it's a perfectly sensible design to use a signal to indicate that the requested data arrived. But if you need to send out every single byte one by one to a consumer, use a listener interface rather than signals and slots.

5. No limits

Because we had the moc for signals and slots, we could add other useful things to it that could not not be done with templates. Among these are scoped translations via a generated tr() function, and an advanced property system with introspection and extended runtime type information. The property system alone is a great advantage: a powerful and generic user interface design tool like Qt Designer would be a lot harder to write - if not impossible - without a powerful and introspective property system. C++ with the moc preprocessor essentially gives us the flexibility of Objective-C or of a Java Runtime Environment, while maintaining C++'s unique performance and scalability advantages. It is what makes Qt the flexible and comfortable tool we have today. */