再次回到QtCoreApplication类

再次回到QtCoreApplication

终于完成了考试,可以恢复正常的生活了,继续我的源码分析之路。不知道会不会进决赛,如果进了,那么又需要一段时间来准备决赛的事情,看来,数据结构是免不了的了,终于要好好去看一次数据结构了。

好了,不说别的了,继续今天的分析。今天,我们又一次来到QtCoreApplication类,看看这个类是怎么调用线程那些东西的。

QtCoreApplication类的exec()方法:

    if (!QCoreApplicationPrivate::checkInstance("exec"))

        return -1;

 

    QThreadData *threadData = self->d_func()->threadData;

    if (threadData != QThreadData::current()) {

        qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());

        return -1;

    }

    if (!threadData->eventLoops.isEmpty()) {

        qWarning("QCoreApplication::exec: The event loop is already running");

        return -1;

    }

 

    threadData->quitNow = false;

    QEventLoop eventLoop;

    self->d_func()->in_exec = true;

    self->d_func()->aboutToQuitEmitted = false;

    int returnCode = eventLoop.exec();

    threadData->quitNow = false;

    if (self) {

        self->d_func()->in_exec = false;

        if (!self->d_func()->aboutToQuitEmitted)

            emit self->aboutToQuit();

        self->d_func()->aboutToQuitEmitted = true;

        sendPostedEvents(0, QEvent::DeferredDelete);

    }

 

    return returnCode;

我重点想知道的是,d_func()函数如何得到QThreadData对象的,这个需要进入到QCoreApplicationPrivate类当中了。

发现了这样的定义:

#define Q_DECLARE_PRIVATE(Class) /

    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } /

    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } /

    friend class Class##Private;

原来该类调用了qGetPtrHelper方法,继续跟踪下去:

template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }

template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }

其实d_func()是将QObjectData类的指针转换为QCoreApplicatPrivate类的指针。看下继承关系,QCoreApplicatPrivate继承自QObjectPrivateQObjectPrivate继承自QObjectData;但是这样的转换还是会带来危险,因为本来这个指针就不是该类的,这样相当于扩大了对象的引用内存的大小,容易产生越界错误。而且这样的强转之后,也只是调用了其中来自 QObjectData的方法,这里的用意不是很明白,应该在其他地方对应用指针做了新的赋值。去找找看。

QScopedPointer<QObjectData> d_ptr的定义来自QObject,现在找找看,是否有对该指针的赋值:

QObject::QObject(QObject *parent): d_ptr(new QObjectPrivate)

实际的引用对象就是QObjectPrivate类的对象了。

现在就可以总结一下了,整个Qt控制台应用程序框架基本明了:

我们编写的代码是:

QCoreApplication a(argc,argv);

a.     exec();

通过这两行代码,Qt为我们做了如下工作:

首先创建一个用于保存整个程序运行核心数据的类对象:

QCoreApplication继承自QObject,所以,首先构造QOjbect类对象,于是有了:

D_ptr(new QObjectPrivate)

随后对QThread进行初始化:

#ifndef QT_NO_THREAD

    QThread::initialize();

#endif

接下来创建事件派送器,从Windows中将消息传递至Qt,并进行分发,构造函数完成。

随后调用a.exec()方法,获取线程信息:

QThreadData *threadData = self->d_func()->threadData;

最后进入事件循环,并进行事件发送等。

 

今天就只能分析到这里了,忙了一天,比较累了,要早点休息了。明天继续,详细看下事件循环部分,随后开始对QApplication类进行分析。

2009111日星期日 23:16

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值