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机制的了解是在太少了,而 ...
随机推荐
- 通过select下拉框里的value控制div显示与隐藏
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 【19.46%】【codeforces 551B】ZgukistringZ
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- Android 让文本输入框默认不获取焦点
项目中有个检索功能,页面上有个EditText输入框,打开页面后,焦点默认在EditText上,这样的话软键盘默认就会显示出来,占据大半个屏幕. 后来想办法将这个给去掉了,原先考虑着将焦点赋给页面上的 ...
- 【a703】求逆序对(树状数组的解法)
Time Limit: 10 second Memory Limit: 2 MB 问题描述 给定一个序列a1,a2...an.如果存在i小于j 并且ai大于aj,那么我们称之为逆序对,求给定序列中逆序 ...
- 【hdu 1864】最大报销额
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...
- duplicate symbols for architecture
duplicate symbols for architecture XCODE编译的时候报错:duplicate symbols for architecture armv7 1.首先排查是 ...
- 数据存储常用5种方式plist、Preference、NSCoding、SQLite3、Core Data
数据存储 iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data ...
- NOIP模拟 - 莫队
题目描述 给定一个元素个数为 n 的整数数组 a 和 Q 个问题,每个问题有 x,y 两个参数,请统计共有多少个整数 K 满足 K 在 a[x]-a[y] 中出现了恰好 K 次. 输入格式 第一行两个 ...
- Android学习--Assets资源文件读取及AssetManager介绍
APK安装过程 复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用 ...
- 【24.63%】【codefroces 686D】Kay and Snowflake
time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standa ...