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机制的了解是在太少了,而 ...
随机推荐
- jquery平滑滚动页面
滚动到顶部 $('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);}); 滚动到指定位置 ...
- Android SqlDelight具体解释和Demo样例
一.简单介绍 SQLDelight 和 SqlBrite 是 Square 公司推出的一个 Android 平台数据库解决方式. 在了解这个两个东西前,必须先得有Andorid的Sqlite的知识(S ...
- js如何操作表格(常用属性方法汇总)
js如何操作表格(常用属性方法汇总) 一.总结 一句话总结: 二.表格相关的属性和方法 1.1 Table 对象集合 cells[] 返回包含表格中所有单元格的一个数组. 语法:tableObject ...
- 流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls
http://blog.csdn.net/tttyd/article/details/12032357 RTP 参考文档 RFC3550/RFC3551 Real-time Tra ...
- 双机热备的Quartz集群
sqlserver搭建高可用双机热备的Quartz集群部署[附源码] 一般拿Timer和Quartz相比较的,简直就是对Quartz的侮辱,两者的功能根本就不在一个层级上,如本篇介绍的Quartz ...
- 卷积神经网络(CNN)的细节问题(滤波器的大小选择)
0. 滤波器的大小选择 大部分卷积神经网络都会采用逐层递增(1⇒ 3 ⇒ 5 ⇒ 7)的方式. 每经过一次池化层,卷积层过滤器的深度都会乘以 2: 1. 权值共享:减轻过拟合 & 降低计算量 ...
- 【38.24%】【codeforces 621E】 Wet Shark and Blocks
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录
获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录 ===========================获取全局上下文(getA ...
- C#--动态操作DataTable
C#动态操作DataTable(新增行.列.查询行.列等) 方法一:动态创建一个DataTable ,并为其添加数据 public void CreateTable() { ...
- .net命名空间和程序集详解
命名空间是一种用于将逻辑上相似的类按层次结构分组的机制.这种机制防止了命名冲突.在这种结构化采用被点号"."分隔的单词来实现.通常最顶层的命名空间是System,例如System; ...