⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qobject.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtCore module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  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.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qobject.h"#include "qobject_p.h"#include "qabstracteventdispatcher.h"#include "qcoreapplication.h"#include "qcoreapplication_p.h"#include "qvariant.h"#include "qmetaobject.h"#include <qregexp.h>#include <qthread.h>#include <private/qthread_p.h>#include <qdebug.h>#include <qhash.h>#include <qpair.h>#include <qvarlengtharray.h>#include <qset.h>#include <qsemaphore.h>#include <new>#include <ctype.h>#include <limits.h>static int DIRECT_CONNECTION_ONLY = 0;Q_GLOBAL_STATIC(QReadWriteLock, qt_object_read_write_lock)QReadWriteLock *QObjectPrivate::readWriteLock() { return qt_object_read_write_lock(); }static int *queuedConnectionTypes(const QList<QByteArray> &typeNames){    int *types = static_cast<int *>(qMalloc((typeNames.count() + 1) * sizeof(int)));    for (int i = 0; i < typeNames.count(); ++i) {        const QByteArray typeName = typeNames.at(i);        if (typeName.endsWith('*'))            types[i] = QMetaType::VoidStar;        else            types[i] = QMetaType::type(typeName);        if (!types[i]) {            qWarning("QObject::connect: Cannot queue arguments of type '%s'\n"                     "(Make sure '%s' is registered using qRegisterMetaType().)",                     typeName.constData(), typeName.constData());            qFree(types);            return 0;        }    }    types[typeNames.count()] = 0;    return types;}struct QConnection {    QObject *sender;    int signal;    QObject *receiver;    int method;    uint refCount:29;    uint type:3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking    int *types;};Q_DECLARE_TYPEINFO(QConnection, Q_MOVABLE_TYPE);class QConnectionList{public:    QReadWriteLock lock;    typedef QMultiHash<const QObject *, int> Hash;    Hash sendersHash, receiversHash;    QList<int> unusedConnections;    typedef QList<QConnection> List;    List connections;    void remove(QObject *object);    void addConnection(QObject *sender, int signal,                       QObject *receiver, int method,                       int type = 0, int *types = 0);    bool removeConnection(QObject *sender, int signal,                          QObject *receiver, int method);};Q_GLOBAL_STATIC(QConnectionList, connectionList)/*! \internal    Removes \a object from the connection list completely, i.e. all    connections containing \a object are removed.*/void QConnectionList::remove(QObject *object){    for (int i = 0; i < 2; ++i) {        Hash &hash1 = i == 0 ? sendersHash : receiversHash;        Hash &hash2 = i == 0 ? receiversHash : sendersHash;        Hash::iterator it = hash1.find(object);        const Hash::iterator end = hash1.end();        while (it != end && it.key() == object) {            const int at = it.value();            QConnection &c = connections[at];            if (c.sender) {                if (c.types && c.types != &DIRECT_CONNECTION_ONLY) {                    qFree(c.types);                    c.types = 0;                }                it = hash1.erase(it);                const QObject * const partner = i == 0 ? c.receiver : c.sender;                Hash::iterator x = hash2.find(partner);                const Hash::iterator xend = hash2.end();                while (x != xend && x.key() == partner) {                    if (x.value() == at) {                        x = hash2.erase(x);                        break;                    } else {                        ++x;                    }                }                uint refCount = c.refCount;                memset(&c, 0, sizeof(c));                c.refCount = refCount;                Q_ASSERT(!unusedConnections.contains(at));                unusedConnections.prepend(at);            } else {                ++it;            }        }    }}/*! \internal    Adds the specified connection.*/void QConnectionList::addConnection(QObject *sender, int signal,                                    QObject *receiver, int method,                                    int type, int *types){    QConnection c = { sender, signal, receiver, method, 0, 0, types };    c.type = type; // don't warn on VC++6    int at = -1;    for (int i = 0; i < unusedConnections.size(); ++i) {        if (!connections.at(unusedConnections.at(i)).refCount) {            // reuse an unused connection            at = unusedConnections.takeAt(i);            connections[at] = c;            break;        }    }    if (at == -1) {        // append new connection        at = connections.size();        connections << c;    }    sendersHash.insert(sender, at);    receiversHash.insert(receiver, at);}/*! \internal    Removes the specified connection.  See QObject::disconnect() for    more information about valid arguments. */bool QConnectionList::removeConnection(QObject *sender, int signal,                                       QObject *receiver, int method){    bool success = false;    Hash::iterator it = sendersHash.find(sender);    while (it != sendersHash.end() && it.key() == sender) {        const int at = it.value();        QConnection &c = connections[at];        if (c.receiver            && (signal < 0 || signal == c.signal)            && (receiver == 0                || (c.receiver == receiver && (method < 0 || method == c.method)))) {            if (c.types) {                if (c.types != &DIRECT_CONNECTION_ONLY)                    qFree(c.types);                c.types = 0;            }            it = sendersHash.erase(it);            Hash::iterator x = receiversHash.find(c.receiver);            const Hash::iterator xend = receiversHash.end();            while (x != xend && x.key() == c.receiver) {                if (x.value() == at) {                    x = receiversHash.erase(x);                    break;                } else {                    ++x;                }            }            uint refCount = c.refCount;            memset(&c, 0, sizeof(c));            c.refCount = refCount;            unusedConnections << at;            success = true;        } else {            ++it;        }    }    return success;}/*  QObjectSet sets the minimum capacity to 4099 (the first prime number  after 4096), so that we can speed up QObject destruction. */class QObjectSet : public QSet<QObject *>{public:    QObjectSet()    { reserve(4099); }};Q_GLOBAL_STATIC(QObjectSet, allObjects)extern "C" Q_CORE_EXPORT void qt_addObject(QObject *object){    QWriteLocker locker(QObjectPrivate::readWriteLock());    QObjectSet *set = allObjects();    if (set)        set->insert(object);}extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *object){    QObjectSet *set = allObjects();    if (set)        set->remove(object);}#ifdef Q_CC_MSVC#pragma warning(push)#pragma warning(disable:4190)#endifextern "C" Q_CORE_EXPORT QList<QObject *> qt_allTopLevelWidgets(){    QList<QObject *> list;    QReadLocker locker(QObjectPrivate::readWriteLock());    const QObjectSet *set = allObjects();    if (!set)        return list;    for (QSet<QObject *>::const_iterator it = set->constBegin(); it != set->constEnd(); ++it) {        if ((*it)->isWidgetType() && !(*it)->parent())            list << *it;    }    return list;}#ifdef Q_CC_MSVC#pragma warning(pop)#endifbool QObjectPrivate::isValidObject(QObject *object){    QObjectSet *set = allObjects();    return set ? set->contains(object) : false;}QObjectPrivate::QObjectPrivate(int version)    : threadData(0), currentSender(0), currentSenderSignalIdStart(-1), currentSenderSignalIdEnd(-1){    if (version != QObjectPrivateVersion)        qFatal("Cannot mix incompatible Qt libraries");    // QObjectData initialization    q_ptr = 0;    parent = 0;                                 // no parent yet. It is set by setParent()    isWidget = false;                           // assume not a widget object    pendTimer = false;                          // no timers yet    blockSig = false;                           // not blocking signals    wasDeleted = false;                         // double-delete catcher    sendChildEvents = true;                     // if we should send ChildInsert and ChildRemove events to parent    receiveChildEvents = true;    postedEvents = 0;    extraData = 0;    connectedSignals = 0;}QObjectPrivate::~QObjectPrivate(){#ifndef QT_NO_USERDATA    if (extraData)        qDeleteAll(extraData->userData);    delete extraData;#endif}#ifdef QT3_SUPPORTvoid QObjectPrivate::sendPendingChildInsertedEvents(){    Q_Q(QObject);    for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {        QObject *c = pendingChildInsertedEvents.at(i);        if (!c)            continue;        QChildEvent childEvent(QEvent::ChildInserted, c);        QCoreApplication::sendEvent(q, &childEvent);    }    pendingChildInsertedEvents.clear();}void QObjectPrivate::removePendingChildInsertedEvents(QObject *child){    if (!child) {        pendingChildInsertedEvents.clear();        return;    }    // the QObject destructor calls QObject::removeChild, which calls    // QCoreApplication::sendEvent() directly.  this can happen while the event    // loop is in the middle of posting events, and when we get here, we may    // not have any more posted events for this object.    // if this is a child remove event and the child insert hasn't    // been dispatched yet, kill that insert    for (int i = 0; i < pendingChildInsertedEvents.size(); ++i) {        QObject *&c = pendingChildInsertedEvents[i];        if (c == child)            c = 0;    }}#endifbool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const{    Q_Q(const QObject);    int signal_index = q->metaObject()->indexOfSignal(signal);    if (signal_index < 0)        return false;    QConnectionList *list = ::connectionList();    QReadLocker locker(&list->lock);    QConnectionList::Hash::const_iterator it = list->sendersHash.constFind(q);    while (it != list->sendersHash.constEnd() && it.key() == q) {        const QConnection &c = list->connections.at(it.value());        if (c.signal == signal_index && c.receiver == receiver)            return true;        ++it;    }    return false;}QObjectList QObjectPrivate::receiverList(const char *signal) const{    Q_Q(const QObject);    QObjectList receivers;    int signal_index = q->metaObject()->indexOfSignal(signal);    if (signal_index < 0)        return receivers;    QConnectionList *list = ::connectionList();    QReadLocker locker(&list->lock);    QConnectionList::Hash::const_iterator it = list->sendersHash.constFind(q);    while (it != list->sendersHash.constEnd() && it.key() == q) {        const QConnection &c = list->connections.at(it.value());        if (c.signal == signal_index)            receivers << c.receiver;        ++it;    }    return receivers;}QObjectList QObjectPrivate::senderList() const{    Q_Q(const QObject);    QObjectList senders;    QConnectionList *list = ::connectionList();    QReadLocker locker(&list->lock);    QConnectionList::Hash::const_iterator it = list->receiversHash.constFind(q);    while (it != list->receiversHash.constEnd() && it.key() == q) {        const QConnection &c = list->connections.at(it.value());        senders << c.sender;        ++it;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -