src/corelib/kernel/qobject.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   143     wasDeleted = false;                         // double-delete catcher
   143     wasDeleted = false;                         // double-delete catcher
   144     sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent
   144     sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent
   145     receiveChildEvents = true;
   145     receiveChildEvents = true;
   146     postedEvents = 0;
   146     postedEvents = 0;
   147     extraData = 0;
   147     extraData = 0;
   148     for (uint i = 0; i < (sizeof connectedSignals / sizeof connectedSignals[0]); ++i)
   148     connectedSignals[0] = connectedSignals[1] = 0;
   149         connectedSignals[i] = 0;
       
   150     inEventHandler = false;
   149     inEventHandler = false;
   151     inThreadChangeEvent = false;
   150     inThreadChangeEvent = false;
   152     deleteWatch = 0;
   151     deleteWatch = 0;
   153     metaObject = 0;
   152     metaObject = 0;
   154     hasGuards = false;
   153     hasGuards = false;
   577     connection with disconnect(). To avoid never ending notification
   576     connection with disconnect(). To avoid never ending notification
   578     loops you can temporarily block signals with blockSignals(). The
   577     loops you can temporarily block signals with blockSignals(). The
   579     protected functions connectNotify() and disconnectNotify() make
   578     protected functions connectNotify() and disconnectNotify() make
   580     it possible to track connections.
   579     it possible to track connections.
   581 
   580 
   582     QObjects organize themselves in object trees. When you create a
   581     QObjects organize themselves in \l {Object Trees and Object
   583     QObject with another object as parent, the object will
   582     Ownership} {object trees}. When you create a QObject with another
   584     automatically add itself to the parent's children() list. The
   583     object as parent, the object will automatically add itself to the
   585     parent takes ownership of the object i.e. it will automatically
   584     parent's children() list. The parent takes ownership of the
   586     delete its children in its destructor. You can look for an object
   585     object; i.e., it will automatically delete its children in its
   587     by name and optionally type using findChild() or findChildren().
   586     destructor. You can look for an object by name and optionally type
       
   587     using findChild() or findChildren().
   588 
   588 
   589     Every object has an objectName() and its class name can be found
   589     Every object has an objectName() and its class name can be found
   590     via the corresponding metaObject() (see QMetaObject::className()).
   590     via the corresponding metaObject() (see QMetaObject::className()).
   591     You can determine whether the object's class inherits another
   591     You can determine whether the object's class inherits another
   592     class in the QObject inheritance hierarchy by using the
   592     class in the QObject inheritance hierarchy by using the
   644     to use your QObject subclass as a value. For example, without a
   644     to use your QObject subclass as a value. For example, without a
   645     copy constructor, you can't use a subclass of QObject as the value
   645     copy constructor, you can't use a subclass of QObject as the value
   646     to be stored in one of the container classes. You must store
   646     to be stored in one of the container classes. You must store
   647     pointers.
   647     pointers.
   648 
   648 
   649     \section2 Auto-Connection
   649     \section1 Auto-Connection
   650 
   650 
   651     Qt's meta-object system provides a mechanism to automatically connect
   651     Qt's meta-object system provides a mechanism to automatically connect
   652     signals and slots between QObject subclasses and their children. As long
   652     signals and slots between QObject subclasses and their children. As long
   653     as objects are defined with suitable object names, and slots follow a
   653     as objects are defined with suitable object names, and slots follow a
   654     simple naming convention, this connection can be performed at run-time
   654     simple naming convention, this connection can be performed at run-time
   658     auto-connection to be performed between widgets on forms created
   658     auto-connection to be performed between widgets on forms created
   659     with \QD. More information about using auto-connection with \QD is
   659     with \QD. More information about using auto-connection with \QD is
   660     given in the \l{Using a Designer UI File in Your Application} section of
   660     given in the \l{Using a Designer UI File in Your Application} section of
   661     the \QD manual.
   661     the \QD manual.
   662 
   662 
   663     \section2 Dynamic Properties
   663     \section1 Dynamic Properties
   664 
   664 
   665     From Qt 4.2, dynamic properties can be added to and removed from QObject
   665     From Qt 4.2, dynamic properties can be added to and removed from QObject
   666     instances at run-time. Dynamic properties do not need to be declared at
   666     instances at run-time. Dynamic properties do not need to be declared at
   667     compile-time, yet they provide the same advantages as static properties
   667     compile-time, yet they provide the same advantages as static properties
   668     and are manipulated using the same API - using property() to read them
   668     and are manipulated using the same API - using property() to read them
   671     From Qt 4.3, dynamic properties are supported by
   671     From Qt 4.3, dynamic properties are supported by
   672     \l{Qt Designer's Widget Editing Mode#The Property Editor}{Qt Designer},
   672     \l{Qt Designer's Widget Editing Mode#The Property Editor}{Qt Designer},
   673     and both standard Qt widgets and user-created forms can be given dynamic
   673     and both standard Qt widgets and user-created forms can be given dynamic
   674     properties.
   674     properties.
   675 
   675 
       
   676     \section1 Internationalization (i18n)
       
   677 
       
   678     All QObject subclasses support Qt's translation features, making it possible
       
   679     to translate an application's user interface into different languages.
       
   680 
       
   681     To make user-visible text translatable, it must be wrapped in calls to
       
   682     the tr() function. This is explained in detail in the
       
   683     \l{Writing Source Code for Translation} document.
       
   684 
   676     \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
   685     \sa QMetaObject, QPointer, QObjectCleanupHandler, Q_DISABLE_COPY()
   677         {Object Trees and Object Ownership}
   686     \sa {Object Trees and Object Ownership}
   678 */
   687 */
   679 
   688 
   680 /*!
   689 /*!
   681     \relates QObject
   690     \relates QObject
   682 
   691 
   833 */
   842 */
   834 
   843 
   835 QObject::~QObject()
   844 QObject::~QObject()
   836 {
   845 {
   837     Q_D(QObject);
   846     Q_D(QObject);
   838     if (d->wasDeleted) {
       
   839 #if defined(QT_DEBUG)
       
   840         qWarning("QObject: Double deletion detected");
       
   841 #endif
       
   842         return;
       
   843     }
       
   844     d->wasDeleted = true;
   847     d->wasDeleted = true;
   845 
       
   846     d->blockSig = 0; // unblock signals so we always emit destroyed()
   848     d->blockSig = 0; // unblock signals so we always emit destroyed()
   847 
   849 
   848     if (!d->isWidget) {
   850     if (!d->isWidget) {
   849         // set all QPointers for this object to zero - note that
   851         // set all QPointers for this object to zero - note that
   850         // ~QWidget() does this for us, so we don't have to do it twice
   852         // ~QWidget() does this for us, so we don't have to do it twice
  2155     Returns a translated version of \a sourceText, optionally based on a
  2157     Returns a translated version of \a sourceText, optionally based on a
  2156     \a disambiguation string and value of \a n for strings containing plurals;
  2158     \a disambiguation string and value of \a n for strings containing plurals;
  2157     otherwise returns \a sourceText itself if no appropriate translated string
  2159     otherwise returns \a sourceText itself if no appropriate translated string
  2158     is available.
  2160     is available.
  2159 
  2161 
  2160     See the sections below on Disambiguation and Handling Plurals for more
  2162     Example:
  2161     information about the optional \a disambiguation and \a n parameters.
       
  2162 
       
  2163     QObject and its subclasses obtain translated strings from any translator
       
  2164     objects that have been installed on the application object; see the
       
  2165     QTranslator documentation for details about this mechanism.
       
  2166 
       
  2167     A translatable string is referenced by its translation context;
       
  2168     this is the name of the QObject subclass whose tr() function is invoked,
       
  2169     as in the following example:
       
  2170 
       
  2171     \snippet mainwindows/sdi/mainwindow.cpp implicit tr context
  2163     \snippet mainwindows/sdi/mainwindow.cpp implicit tr context
  2172     \dots
  2164     \dots
  2173 
       
  2174     Here, the context is \c MainWindow because it is the \c MainWindow::tr()
       
  2175     function that is invoked. Translation contexts can be given explicitly
       
  2176     by fully qualifying the call to tr(); for example:
       
  2177 
       
  2178     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp explicit tr context
       
  2179 
       
  2180     This call obtains the translated text for "Page up" from the \c QScrollBar
       
  2181     context.
       
  2182 
       
  2183     \section1 Defining Translation Contexts
       
  2184 
       
  2185     The translation context for QObject and each QObject subclass is the
       
  2186     class name itself. Developers subclassing QObject must use the
       
  2187     Q_OBJECT macro in their class definition to override the translation
       
  2188     context. This macro sets the context to the name of the subclass.
       
  2189 
       
  2190     If Q_OBJECT is not used in a class definition, the context will be
       
  2191     inherited from the base class. For example, since all QObject-based
       
  2192     classes in Qt provide a context, a new QWidget subclass defined without
       
  2193     a Q_OBJECT macro will use the "QWidget" context if its tr() function
       
  2194     is invoked.
       
  2195 
       
  2196     \section1 Translator Comments
       
  2197 
       
  2198     Developers can include information about each translatable string to
       
  2199     help translators with the translation process. These are extracted
       
  2200     when \l lupdate is used to process the source files. The recommended
       
  2201     way to add comments is to annotate the tr() calls in your code with
       
  2202     comments of the form:
       
  2203 
       
  2204     \tt{//: ...}
       
  2205 
       
  2206     or
       
  2207 
       
  2208     \tt{\begincomment: ... \endcomment}
       
  2209 
       
  2210     Examples:
       
  2211 
       
  2212     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 40
       
  2213 
       
  2214     In these examples, the comments will be associated with the strings
       
  2215     passed to tr() in the context of each call.
       
  2216 
       
  2217     \section1 Disambiguation
       
  2218 
  2165 
  2219     If the same \a sourceText is used in different roles within the
  2166     If the same \a sourceText is used in different roles within the
  2220     same context, an additional identifying string may be passed in
  2167     same context, an additional identifying string may be passed in
  2221     \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
  2168     \a disambiguation (0 by default). In Qt 4.4 and earlier, this was
  2222     the preferred way to pass comments to translators.
  2169     the preferred way to pass comments to translators.
  2223 
  2170 
  2224     Example:
  2171     Example:
  2225 
  2172 
  2226     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
  2173     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 17
  2227 
  2174     \dots
  2228     \section1 Meta Data
  2175 
  2229 
  2176     See \l{Writing Source Code for Translation} for a detailed description of
  2230     Additional data can be attached to each translatable message.
  2177     Qt's translation mechanisms in general, and the
  2231     The syntax:
  2178     \l{Writing Source Code for Translation#Disambiguation}{Disambiguation}
  2232 
  2179     section for information on disambiguation.
  2233     \tt{//= <id>}
       
  2234 
       
  2235     can be used to give the message a unique identifier to support tools
       
  2236     which need it.
       
  2237     The syntax:
       
  2238 
       
  2239     \tt{//~ <field name> <field contents>}
       
  2240 
       
  2241     can be used to attach meta data to the message. The field name should consist
       
  2242     of a domain prefix (possibly the conventional file extension of the file format
       
  2243     the field is inspired by), a hyphen and the actual field name in
       
  2244     underscore-delimited notation. For storage in TS files, the field name together
       
  2245     with the prefix "extra-" will form an XML element name. The field contents will
       
  2246     be XML-escaped, but otherwise appear verbatim as the element's contents.
       
  2247     Any number of unique fields can be added to each message.
       
  2248 
       
  2249     Example:
       
  2250 
       
  2251     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp meta data
       
  2252 
       
  2253     Meta data appearing right in front of a magic TRANSLATOR comment applies to the
       
  2254     whole TS file.
       
  2255 
       
  2256     \section1 Character Encodings
       
  2257 
       
  2258     You can set the encoding for \a sourceText by calling QTextCodec::setCodecForTr().
       
  2259     By default \a sourceText is assumed to be in Latin-1 encoding.
       
  2260 
       
  2261     \section1 Handling Plurals
       
  2262 
       
  2263     If \a n >= 0, all occurrences of \c %n in the resulting string
       
  2264     are replaced with a decimal representation of \a n. In addition,
       
  2265     depending on \a n's value, the translation text may vary.
       
  2266 
       
  2267     Example:
       
  2268 
       
  2269     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 18
       
  2270 
       
  2271     The table below shows what string is returned depending on the
       
  2272     active translation:
       
  2273 
       
  2274     \table
       
  2275     \header \o      \o{3,1} Active Translation
       
  2276     \header \o \a n \o No Translation        \o French                                 \o English
       
  2277     \row    \o 0    \o "0 message(s) saved"  \o "0 message sauvegard\unicode{0xE9}"    \o "0 message\bold{s} saved"
       
  2278     \row    \o 1    \o "1 message(s) saved"  \o "1 message sauvegard\unicode{0xE9}"    \o "1 message saved"
       
  2279     \row    \o 2    \o "2 message(s) saved"  \o "2 message\bold{s} sauvegard\unicode{0xE9}\bold{s}"  \o "2 message\bold{s} saved"
       
  2280     \row    \o 37   \o "37 message(s) saved" \o "37 message\bold{s} sauvegard\unicode{0xE9}\bold{s}" \o "37 message\bold{s} saved"
       
  2281     \endtable
       
  2282 
       
  2283     This idiom is more flexible than the traditional approach; e.g.,
       
  2284 
       
  2285     \snippet doc/src/snippets/code/src_corelib_kernel_qobject.cpp 19
       
  2286 
       
  2287     because it also works with target languages that have several
       
  2288     plural forms (e.g., Irish has a special "dual" form that should
       
  2289     be used when \c n is 2), and it handles the \e n == 0 case
       
  2290     correctly for languages such as French that require the singular.
       
  2291     See the \l{Qt Linguist Manual} for details.
       
  2292 
       
  2293     Instead of \c %n, you can use \c %Ln to produce a localized
       
  2294     representation of \a n. The conversion uses the default locale,
       
  2295     set using QLocale::setDefault(). (If no default locale was
       
  2296     specified, the "C" locale is used.)
       
  2297 
  2180 
  2298     \warning This method is reentrant only if all translators are
  2181     \warning This method is reentrant only if all translators are
  2299     installed \e before calling this method. Installing or removing
  2182     installed \e before calling this method. Installing or removing
  2300     translators while performing translations is not supported. Doing
  2183     translators while performing translations is not supported. Doing
  2301     so will probably result in crashes or other undesirable behavior.
  2184     so will probably result in crashes or other undesirable behavior.
  2966 
  2849 
  2967 void QObject::disconnectNotify(const char *)
  2850 void QObject::disconnectNotify(const char *)
  2968 {
  2851 {
  2969 }
  2852 }
  2970 
  2853 
       
  2854 /* \internal
       
  2855     convert a signal index from the method range to the signal range
       
  2856  */
       
  2857 static int methodIndexToSignalIndex(const QMetaObject *metaObject, int signal_index)
       
  2858 {
       
  2859     if (signal_index < 0)
       
  2860         return signal_index;
       
  2861     while (metaObject && metaObject->methodOffset() > signal_index)
       
  2862         metaObject = metaObject->superClass();
       
  2863 
       
  2864     if (metaObject) {
       
  2865         int signalOffset, methodOffset;
       
  2866         computeOffsets(metaObject, &signalOffset, &methodOffset);
       
  2867         if (signal_index < metaObject->methodCount())
       
  2868             signal_index = QMetaObjectPrivate::originalClone(metaObject, signal_index - methodOffset) + signalOffset;
       
  2869         else
       
  2870             signal_index = signal_index - methodOffset + signalOffset;
       
  2871     }
       
  2872     return signal_index;
       
  2873 }
       
  2874 
  2971 /*!\internal
  2875 /*!\internal
  2972    \a types is a 0-terminated vector of meta types for queued
  2876    \a types is a 0-terminated vector of meta types for queued
  2973    connections.
  2877    connections.
  2974 
  2878 
  2975    if \a signal_index is -1, then we effectively connect *all* signals
  2879    if \a signal_index is -1, then we effectively connect *all* signals
  2976    from the sender to the receiver's slot
  2880    from the sender to the receiver's slot
  2977  */
  2881  */
  2978 bool QMetaObject::connect(const QObject *sender, int signal_index,
  2882 bool QMetaObject::connect(const QObject *sender, int signal_index,
  2979                           const QObject *receiver, int method_index, int type, int *types)
  2883                           const QObject *receiver, int method_index, int type, int *types)
  2980 {
  2884 {
  2981     if (signal_index > 0) {
  2885     signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
  2982         const QMetaObject *mo = sender->metaObject();
       
  2983         while (mo && mo->methodOffset() > signal_index)
       
  2984             mo = mo->superClass();
       
  2985         if (mo) {
       
  2986             int signalOffset, methodOffset;
       
  2987             computeOffsets(mo, &signalOffset, &methodOffset);
       
  2988             signal_index = QMetaObjectPrivate::originalClone(mo, signal_index - methodOffset) + signalOffset;
       
  2989         }
       
  2990     }
       
  2991     return QMetaObjectPrivate::connect(sender, signal_index,
  2886     return QMetaObjectPrivate::connect(sender, signal_index,
  2992                                        receiver, method_index, type, types);
  2887                                        receiver, method_index, type, types);
  2993 }
  2888 }
  2994 
  2889 
  2995 /*! \internal
  2890 /*! \internal
  3040     if (c->next)
  2935     if (c->next)
  3041         c->next->prev = &c->next;
  2936         c->next->prev = &c->next;
  3042 
  2937 
  3043     QObjectPrivate *const sender_d = QObjectPrivate::get(s);
  2938     QObjectPrivate *const sender_d = QObjectPrivate::get(s);
  3044     if (signal_index < 0) {
  2939     if (signal_index < 0) {
  3045         for (uint i = 0; i < (sizeof sender_d->connectedSignals
  2940         sender_d->connectedSignals[0] = sender_d->connectedSignals[1] = ~0;
  3046                               / sizeof sender_d->connectedSignals[0] ); ++i)
  2941     } else if (signal_index < (int)sizeof(sender_d->connectedSignals) * 8) {
  3047             sender_d->connectedSignals[i] = ~0u;
  2942         sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f));
  3048     } else if (signal_index < (int)sizeof sender_d->connectedSignals * 8) {
       
  3049         uint n = (signal_index / (8 * sizeof sender_d->connectedSignals[0]));
       
  3050         sender_d->connectedSignals[n] |= (1 << (signal_index - n * 8
       
  3051                                     * sizeof sender_d->connectedSignals[0]));
       
  3052     }
  2943     }
  3053 
  2944 
  3054     return true;
  2945     return true;
  3055 }
  2946 }
  3056 
  2947 
  3058 /*!\internal
  2949 /*!\internal
  3059  */
  2950  */
  3060 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
  2951 bool QMetaObject::disconnect(const QObject *sender, int signal_index,
  3061                              const QObject *receiver, int method_index)
  2952                              const QObject *receiver, int method_index)
  3062 {
  2953 {
  3063     if (signal_index > 0) {
  2954     signal_index = methodIndexToSignalIndex(sender->metaObject(), signal_index);
  3064         const QMetaObject *mo = sender->metaObject();
       
  3065         while (mo && mo->methodOffset() > signal_index)
       
  3066             mo = mo->superClass();
       
  3067         if (mo) {
       
  3068             int signalOffset, methodOffset;
       
  3069             computeOffsets(mo, &signalOffset, &methodOffset);
       
  3070             signal_index = QMetaObjectPrivate::originalClone(mo, signal_index - methodOffset) + signalOffset;
       
  3071         }
       
  3072     }
       
  3073     return QMetaObjectPrivate::disconnect(sender, signal_index,
  2955     return QMetaObjectPrivate::disconnect(sender, signal_index,
  3074                                           receiver, method_index);
  2956                                           receiver, method_index);
  3075 }
  2957 }
  3076 
  2958 
  3077 /*! \internal
  2959 /*! \internal
  3304     int signalOffset;
  3186     int signalOffset;
  3305     int methodOffset;
  3187     int methodOffset;
  3306     computeOffsets(m, &signalOffset, &methodOffset);
  3188     computeOffsets(m, &signalOffset, &methodOffset);
  3307 
  3189 
  3308     int signal_index = signalOffset + local_signal_index;
  3190     int signal_index = signalOffset + local_signal_index;
  3309     if (signal_index < (int)sizeof(sender->d_func()->connectedSignals) * 8
  3191 
  3310         && !qt_signal_spy_callback_set.signal_begin_callback
  3192     if (!sender->d_func()->isSignalConnected(signal_index))
  3311         && !qt_signal_spy_callback_set.signal_end_callback) {
  3193         return; // nothing connected to these signals, and no spy
  3312         uint n = (signal_index / (8 * sizeof sender->d_func()->connectedSignals[0]));
       
  3313         uint m = 1 << (signal_index - n * 8 * sizeof sender->d_func()->connectedSignals[0]);
       
  3314         if ((sender->d_func()->connectedSignals[n] & m) == 0)
       
  3315             // nothing connected to these signals, and no spy
       
  3316             return;
       
  3317     }
       
  3318 
  3194 
  3319     if (sender->d_func()->blockSig)
  3195     if (sender->d_func()->blockSig)
  3320         return;
  3196         return;
  3321 
  3197 
  3322     int signal_absolute_index = methodOffset + local_signal_index;
  3198     int signal_absolute_index = methodOffset + local_signal_index;
  3471         return relative_index;
  3347         return relative_index;
  3472     relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
  3348     relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
  3473     int signalOffset, methodOffset;
  3349     int signalOffset, methodOffset;
  3474     computeOffsets(base, &signalOffset, &methodOffset);
  3350     computeOffsets(base, &signalOffset, &methodOffset);
  3475     return relative_index + signalOffset;
  3351     return relative_index + signalOffset;
  3476 }
       
  3477 
       
  3478 /*! \internal
       
  3479 
       
  3480   Returns true if the signal with index \a signal_index from object \a sender is connected.
       
  3481   Signals with indices above a certain range are always considered connected (see connectedSignals
       
  3482   in QObjectPrivate). If a signal spy is installed, all signals are considered connected.
       
  3483 
       
  3484   \a signal_index must be the index returned by QObjectPrivate::signalIndex;
       
  3485 */
       
  3486 bool QObjectPrivate::isSignalConnected(int signal_index) const
       
  3487 {
       
  3488     if (signal_index < (int)sizeof(connectedSignals) * 8
       
  3489         && !qt_signal_spy_callback_set.signal_begin_callback
       
  3490         && !qt_signal_spy_callback_set.signal_end_callback) {
       
  3491         uint n = (signal_index / (8 * sizeof connectedSignals[0]));
       
  3492         uint m = 1 << (signal_index - n * 8 * sizeof connectedSignals[0]);
       
  3493         if ((connectedSignals[n] & m) == 0)
       
  3494             // nothing connected to these signals, and no spy
       
  3495             return false;
       
  3496     }
       
  3497     return true;
       
  3498 }
  3352 }
  3499 
  3353 
  3500 /*****************************************************************************
  3354 /*****************************************************************************
  3501   Properties
  3355   Properties
  3502  *****************************************************************************/
  3356  *****************************************************************************/