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机制的了解是在太少了,而 ...
随机推荐
- MQ选型对比RabbitMQ RocketMQ ActiveMQ
原文:MQ选型对比RabbitMQ RocketMQ ActiveMQ 几种MQ产品说明: ZeroMQ : 扩展性好,开发比较灵活,采用C语言实现,实际上他只是一个socket库的重新封装 ...
- Sqlplus的一般操作
Sqlplus一些必要操作指令 1, 登陆sys 用户,需要加上 as sysdba Connect sys as sysdba; Input your password; Connected; 2, ...
- windows 安装 RabbitMQ 并添加用户 – 畅玩Coding
原文:windows 安装 RabbitMQ 并添加用户 – 畅玩Coding 1.RabbitMQ 使用 Eralng,所以需要先安装 Eralng 下载: http://www.erlang.or ...
- 【13.91%】【codeforces 593D】Happy Tree Party
time limit per test3 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- htmlunit 模拟登录 无验证码
1.模拟登录csdn,最开始的时候使用的是httpclient,网上的所有模拟登录csdn的版本都是找到lt/execution/event_id.连同用户名及密码 一起发送即可,但是目前的csdn的 ...
- Configure Two DataSources ---
67. Data Access 67.1 Configure a DataSource To override the default settings just define a @Bean of ...
- 【u114】旅行计划(12月你好)
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小明要去一个国家旅游.这个国家有N个城市,编号为1-N,并且有M条道路连接着,小明准备从其中一个城市出 ...
- 使用readLine()方法遇到的坑
程序很简单,客户段从控制台读取用户输入,然后发送至服务器端,主要代码如下 服务端代码: 客户端代码: 结果运行的时候,当开启服务端和客户端后,在客户端的控制台 键盘输入 内容,服务端却没有显示内容 原 ...
- WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)
原文 WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object) 众所周知的,WPF 中多数对象都继承自 Dispatch ...
- 写在使用 Linux 工作一年后
start 去年公司空了几台台式机,当时看了下似乎配置比我用的乞丐版 air 略高一些,而且除了 ssd 以外还有一个 1T 的大硬盘,加上后面可能会有一段时间不做 iOS 了,那就不需要 macOS ...