QEventLoop的全部源码也不多,混个脸熟
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/ #include "qeventloop.h" #include "qabstracteventdispatcher.h"
#include "qcoreapplication.h"
#include "qcoreapplication_p.h"
#include "qelapsedtimer.h" #include "qobject_p.h"
#include "qeventloop_p.h"
#include <private/qthread_p.h> QT_BEGIN_NAMESPACE /*!
\class QEventLoop
\inmodule QtCore
\brief The QEventLoop class provides a means of entering and leaving an event loop. At any time, you can create a QEventLoop object and call exec()
on it to start a local event loop. From within the event loop,
calling exit() will force exec() to return. \sa QAbstractEventDispatcher
*/ /*!
\enum QEventLoop::ProcessEventsFlag This enum controls the types of events processed by the
processEvents() functions. \value AllEvents All events. Note that
\l{QEvent::DeferredDelete}{DeferredDelete} events are processed
specially. See QObject::deleteLater() for more details. \value ExcludeUserInputEvents Do not process user input events,
such as ButtonPress and KeyPress. Note that the events are not
discarded; they will be delivered the next time processEvents() is
called without the ExcludeUserInputEvents flag. \value ExcludeSocketNotifiers Do not process socket notifier
events. Note that the events are not discarded; they will be
delivered the next time processEvents() is called without the
ExcludeSocketNotifiers flag. \value WaitForMoreEvents Wait for events if no pending events are
available. \omitvalue X11ExcludeTimers
\omitvalue EventLoopExec
\omitvalue DialogExec \sa processEvents()
*/ /*!
Constructs an event loop object with the given \a parent.
*/
QEventLoop::QEventLoop(QObject *parent)
: QObject(*new QEventLoopPrivate, parent)
{
Q_D(QEventLoop);
if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) {
qWarning("QEventLoop: Cannot be used without QApplication");
} else if (!d->threadData->eventDispatcher.load()) {
QThreadPrivate::createEventDispatcher(d->threadData);
}
} /*!
Destroys the event loop object.
*/
QEventLoop::~QEventLoop()
{ } /*!
Processes pending events that match \a flags until there are no
more events to process. Returns \c true if pending events were handled;
otherwise returns \c false. This function is especially useful if you have a long running
operation and want to show its progress without allowing user
input; i.e. by using the \l ExcludeUserInputEvents flag. This function is simply a wrapper for
QAbstractEventDispatcher::processEvents(). See the documentation
for that function for details.
*/
bool QEventLoop::processEvents(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
if (!d->threadData->eventDispatcher.load())
return false;
return d->threadData->eventDispatcher.load()->processEvents(flags);
} /*!
Enters the main event loop and waits until exit() is called.
Returns the value that was passed to exit(). If \a flags are specified, only events of the types allowed by
the \a flags will be processed. It is necessary to call this function to start event handling. The
main event loop receives events from the window system and
dispatches these to the application widgets. Generally speaking, no user interaction can take place before
calling exec(). As a special case, modal widgets like QMessageBox
can be used before calling exec(), because modal widgets
use their own local event loop. To make your application perform idle processing (i.e. executing a
special function whenever there are no pending events), use a
QTimer with 0 timeout. More sophisticated idle processing schemes
can be achieved using processEvents(). \sa QCoreApplication::quit(), exit(), processEvents()
*/
int QEventLoop::exec(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
//we need to protect from race condition with QThread::exit
QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(d->threadData->thread))->mutex);
if (d->threadData->quitNow)
return -; if (d->inExec) {
qWarning("QEventLoop::exec: instance %p has already called exec()", this);
return -;
} struct LoopReference {
QEventLoopPrivate *d;
QMutexLocker &locker; bool exceptionCaught;
LoopReference(QEventLoopPrivate *d, QMutexLocker &locker) : d(d), locker(locker), exceptionCaught(true)
{
d->inExec = true;
d->exit.storeRelease(false);
++d->threadData->loopLevel;
d->threadData->eventLoops.push(d->q_func());
locker.unlock();
} ~LoopReference()
{
if (exceptionCaught) {
qWarning("Qt has caught an exception thrown from an event handler. Throwing\n"
"exceptions from an event handler is not supported in Qt.\n"
"You must not let any exception whatsoever propagate through Qt code.\n"
"If that is not possible, in Qt 5 you must at least reimplement\n"
"QCoreApplication::notify() and catch all exceptions there.\n");
}
locker.relock();
QEventLoop *eventLoop = d->threadData->eventLoops.pop();
Q_ASSERT_X(eventLoop == d->q_func(), "QEventLoop::exec()", "internal error");
Q_UNUSED(eventLoop); // --release warning
d->inExec = false;
--d->threadData->loopLevel;
}
};
LoopReference ref(d, locker); // remove posted quit events when entering a new event loop
QCoreApplication *app = QCoreApplication::instance();
if (app && app->thread() == thread())
QCoreApplication::removePostedEvents(app, QEvent::Quit); while (!d->exit.loadAcquire())
processEvents(flags | WaitForMoreEvents | EventLoopExec); ref.exceptionCaught = false;
return d->returnCode.load();
} /*!
Process pending events that match \a flags for a maximum of \a
maxTime milliseconds, or until there are no more events to
process, whichever is shorter.
This function is especially useful if you have a long running
operation and want to show its progress without allowing user
input, i.e. by using the \l ExcludeUserInputEvents flag. \b{Notes:}
\list
\li This function does not process events continuously; it
returns after all available events are processed.
\li Specifying the \l WaitForMoreEvents flag makes no sense
and will be ignored.
\endlist
*/
void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
{
Q_D(QEventLoop);
if (!d->threadData->eventDispatcher.load())
return; QElapsedTimer start;
start.start();
while (processEvents(flags & ~WaitForMoreEvents)) {
if (start.elapsed() > maxTime)
break;
}
} /*!
Tells the event loop to exit with a return code. After this function has been called, the event loop returns from
the call to exec(). The exec() function returns \a returnCode. By convention, a \a returnCode of 0 means success, and any non-zero
value indicates an error. Note that unlike the C library function of the same name, this
function \e does return to the caller -- it is event processing that
stops. \sa QCoreApplication::quit(), quit(), exec()
*/
void QEventLoop::exit(int returnCode)
{
Q_D(QEventLoop);
if (!d->threadData->eventDispatcher.load())
return; d->returnCode.store(returnCode);
d->exit.storeRelease(true);
d->threadData->eventDispatcher.load()->interrupt();
} /*!
Returns \c true if the event loop is running; otherwise returns
false. The event loop is considered running from the time when
exec() is called until exit() is called. \sa exec(), exit()
*/
bool QEventLoop::isRunning() const
{
Q_D(const QEventLoop);
return !d->exit.loadAcquire();
} /*!
Wakes up the event loop. \sa QAbstractEventDispatcher::wakeUp()
*/
void QEventLoop::wakeUp()
{
Q_D(QEventLoop);
if (!d->threadData->eventDispatcher.load())
return;
d->threadData->eventDispatcher.load()->wakeUp();
} /*!
\reimp
*/
bool QEventLoop::event(QEvent *event)
{
if (event->type() == QEvent::Quit) {
quit();
return true;
} else {
return QObject::event(event);
}
} /*!
Tells the event loop to exit normally. Same as exit(0). \sa QCoreApplication::quit(), exit()
*/
void QEventLoop::quit()
{ exit(); } class QEventLoopLockerPrivate
{
public:
explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop)
: loop(loop), type(EventLoop)
{
loop->ref();
} explicit QEventLoopLockerPrivate(QThreadPrivate *thread)
: thread(thread), type(Thread)
{
thread->ref();
} explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app)
: app(app), type(Application)
{
app->ref();
} ~QEventLoopLockerPrivate()
{
switch (type)
{
case EventLoop:
loop->deref();
break;
case Thread:
thread->deref();
break;
default:
app->deref();
break;
}
} private:
union {
QEventLoopPrivate * loop;
QThreadPrivate * thread;
QCoreApplicationPrivate * app;
};
enum Type {
EventLoop,
Thread,
Application
};
const Type type;
}; /*!
\class QEventLoopLocker
\inmodule QtCore
\brief The QEventLoopLocker class provides a means to quit an event loop when it is no longer needed.
\since 5.0 The QEventLoopLocker operates on particular objects - either a QCoreApplication
instance, a QEventLoop instance or a QThread instance. This makes it possible to, for example, run a batch of jobs with an event loop
and exit that event loop after the last job is finished. That is accomplished
by keeping a QEventLoopLocker with each job instance. The variant which operates on QCoreApplication makes it possible to finish
asynchronously running jobs after the last gui window has been closed. This
can be useful for example for running a job which uploads data to a network. \sa QEventLoop, QCoreApplication
*/ /*!
Creates an event locker operating on the QCoreApplication. The application will quit when there are no more QEventLoopLockers operating on it. \sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled()
*/
QEventLoopLocker::QEventLoopLocker()
: d_ptr(new QEventLoopLockerPrivate(static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(QCoreApplication::instance()))))
{ } /*!
Creates an event locker operating on the \a loop. This particular QEventLoop will quit when there are no more QEventLoopLockers operating on it. \sa QEventLoop::quit()
*/
QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
: d_ptr(new QEventLoopLockerPrivate(static_cast<QEventLoopPrivate*>(QObjectPrivate::get(loop))))
{ } /*!
Creates an event locker operating on the \a thread. This particular QThread will quit when there are no more QEventLoopLockers operating on it. \sa QThread::quit()
*/
QEventLoopLocker::QEventLoopLocker(QThread *thread)
: d_ptr(new QEventLoopLockerPrivate(static_cast<QThreadPrivate*>(QObjectPrivate::get(thread))))
{ } /*!
Destroys this event loop locker object
*/
QEventLoopLocker::~QEventLoopLocker()
{
delete d_ptr;
} QT_END_NAMESPACE
QEventLoop的全部源码也不多,混个脸熟的更多相关文章
- Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)
事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...
- jQuery-1.9.1源码分析系列(二)jQuery选择器续2——筛选
前面分析了选择器的结构和几个解析函数,接下来分析jQuery对象的伪类选择器.这里所谓的jQuery对象的伪类选择器就是从已有的jQuery对象(元素集合)中筛选出指定的集合出来. 4. jQu ...
- 你的文章里为什么不放源码Github链接了
"你的文章里为什么不放源码Github链接了?",一个读者这么问我 我把这张图发给了他,这是我之前放文章中Demo源码的Github仓库 他一脸疑惑,问我怎么了 经常使用Githu ...
- 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 百篇博客分析OpenHarmony源码 | v53.02
百篇博客系列篇.本篇为: v53.xx 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应 ...
- Qt获得网页源码
1.工程中添加网络模块 打开你的.pro文件插入以下代码 QT += network 2.添加代码 CodeQString NetWork::getWebSource(QUrl url) { QNet ...
- QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数
QT源码解析(一) QT创建窗口程序.消息循环和WinMain函数 分类: QT2009-10-28 13:33 17695人阅读 评论(13) 收藏 举报 qtapplicationwindowse ...
- QT:轻松获取网页源码
获取网页源码的小例子,代码很简单,就不多作解释了. 不过一定要注意网页的编码问题,否则会出现乱码的!!! #include <QtCore> #include <QtNetwork& ...
- github上的QT源码,必要的时候还是应该看一下,仅凭猜测很容易出错
QCoreApplication::processEvents 他处理的时候拿的是current不是qAppqApp的话,才是和主线程密切相关的 一直觉得QT源码复杂,有点怕,所以没怎么看 我也看不懂 ...
- QT源码分析(从QApplication开始)
QT源码分析 转载自:http://no001.blog.51cto.com/1142339/282130 今天,在给同学讲东西的时候,谈到了Qt源代码的问题,才发现自己对Qt机制的了解是在太少了,而 ...
随机推荐
- 【u002】数列排序(seqsort)
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交 ...
- [Grid Layout] Describe a grid layout using grid-template-areas
We can describe the nature of a grid in an ‘ASCII-art’ way with grid-template-areas. Let’s see how t ...
- css画电脑键盘
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Distribution download cancelled. Using distribution from 'https://services.gradle.org/distributions/
Distribution download cancelled. Using distribution from ‘https://services.gradle.org/distributions/ ...
- Android BlueDroid(一):BlueDroid概述
关键词:bluedroid bluez作者:xubin341719(欢迎转载,请注明作者,请尊重版权,谢谢!)欢迎指正错误.共同学习.共同进步!! 一.名词解释:(实用信息添加中--) BTI F: ...
- html5常用属性text-shadow、vertical-align、background如何使用
html5常用属性text-shadow.vertical-align.background如何使用 一.总结 一句话总结: 1.text-shadow:[x轴(X Offset) y轴(Y Offs ...
- 高CPU、数据库无法读写
高CPU.数据库无法读写的真凶 有兴趣的同学可以参考如下系列文章,都是针对dump分析的实战和总结: Windbg DUMP分析(原创汇总) http://www.cnblogs.com/Love ...
- Python应用库大全总结
学python,想必大家都是从爬虫开始的吧.毕竟网上类似的资源很丰富,开源项目也非常多. python学习网络爬虫主要分3个大的版块:抓取,分析,存储 当我们在浏览器中输入一个url后回车,后台会发生 ...
- Opencv光流运动物体追踪
光流的概念是由一个叫Gibson的哥们在1950年提出来的.它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存 ...
- javascript数据结构与算法 零(前记+前言)
前记 这本书Data Structure and Algorithm with Javascript 我将其翻译成<< javascript 数据结构和算法>> 为什么这么翻译 ...