QEventLoop
QEventLoop 是一个事件循环类,用来接收和分发事件的主循环,Qt中使用 事件循环来接收事件、信号和执行异步操作
class Q_CORE_EXPORT QEventLoop : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QEventLoop)
public:
explicit QEventLoop(QObject *parent = 0);
~QEventLoop();
enum ProcessEventsFlag { //事件标志
AllEvents = 0x00,
ExcludeUserInputEvents = 0x01,
ExcludeSocketNotifiers = 0x02,
WaitForMoreEvents = 0x04,
#ifdef QT3_SUPPORT
ExcludeUserInput = ExcludeUserInputEvents,
WaitForMore = WaitForMoreEvents,
#endif
X11ExcludeTimers = 0x08
#ifdef QT_DEPRECATED
, DeferredDeletion = 0x10
#endif
, EventLoopExec = 0x20
, DialogExec = 0x40
};
Q_DECLARE_FLAGS(ProcessEventsFlags, ProcessEventsFlag)
//开启事件循环,可以传入 ProcessEventsFlags 过滤特定类型事件。
bool processEvents(ProcessEventsFlags flags = AllEvents);
//增加了一个最大时间参数,可以限制事件处理的最长时间。
void processEvents(ProcessEventsFlags flags, int maximumTime);
int exec(ProcessEventsFlags flags = AllEvents); //调用事件循环
void exit(int returnCode = 0); //退出事件循环
bool isRunning() const; //返回事件循环是否在运行
void wakeUp(); //唤醒事件循环
public Q_SLOTS:
void quit(); //退出时被调用
};
//QEventLoop 的私有实现类
class QEventLoopPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QEventLoop)
public:
inline QEventLoopPrivate()
: exit(true), inExec(false), returnCode(-1) //初始化 QEventLoop
{ }
bool exit, inExec;
int returnCode;
};
//构造函数,赋值d指针,创建事件分发器
QEventLoop::QEventLoop(QObject *parent)
: QObject(*new QEventLoopPrivate, parent)
//将事件分发到线程的事件分发器,包含删除时,广播删除事件,在下次事件循环时手动回收资源
bool QEventLoop::processEvents(ProcessEventsFlags flags)
//调用 processEvents,使用 QTime 进行计时,超时 maxTime 退出
void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
//执行事件循环,一直调用 processEvents ,直到 exit为真退出
int QEventLoop::exec(ProcessEventsFlags flags)
//手动退出事件循环,设置退出值,中断事件分发器等待,让事件循环去检查 d—>exit 标记,退出 事件的exec
void QEventLoop::exit(int returnCode)
//返回事件 return !d->exit;
bool QEventLoop::isRunning() const
//唤醒事件分发器,
void QEventLoop::wakeUp()
//退出
void QEventLoop::quit()
应用举例:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
QEventLoop eventLoop;
// 工作线程
void workerThread()
{
// 模拟工作线程执行任务
qDebug() << "Worker thread started.";
QThread::sleep(3);
qDebug() << "Worker thread finished.";
// 条件满足时唤醒主线程
eventLoop.quit();
}
// 主线程中等待条件满足
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 启动工作线程
QThread* thread = new QThread;
QObject::connect(thread, &QThread::started, workerThread);
thread->start();
// 等待条件满足
qDebug() << "Main thread waiting...";
eventLoop.exec(); //这里事件循环会阻塞直到 事件循环退出
qDebug() << "Main thread resumed.";
return a.exec();
}
cpp
// 下载管理器
class DownloadManager : public QObject
{
Q_OBJECT
public:
void addDownload(QUrl url); // 添加下载任务
private:
QList<DownloadTask*> tasks; // 下载任务列表
};
// 单个下载任务
class DownloadTask : public QObject
{
Q_OBJECT
public:
DownloadTask(QUrl url);
void run(); // 下载线程函数
private:
QEventLoop *loop; // 事件循环
QNetworkAccessManager *manager; // 网络请求管理器
};
// 添加下载任务
void DownloadManager::addDownload(QUrl url)
{
// 创建下载任务
DownloadTask *task = new DownloadTask(url);
tasks.append(task);
// 将任务移动到新线程
QThread *thread = new QThread();
task->moveToThread(thread);
// 连接信号槽,在线程启动后执行下载
connect(thread, &QThread::started, task, &DownloadTask::run);
// 启动线程
thread->start();
}
// 下载线程函数
void DownloadTask::run()
{
// 创建事件循环
loop = new QEventLoop();
// 发起网络请求获取数据
QNetworkReply *reply = manager->get(QNetworkRequest(url));
// 在下载进度变化时,调用 wakeUp() 唤醒 GUI 线程
QObject::connect(reply, &QNetworkReply::downloadProgress,
[=](qint64 bytesReceived, qint64 bytesTotal) {
updateProgress(); // 更新进度
loop->wakeUp(); // 唤醒 GUI 线程
});
// 执行事件循环,等待下载完成
loop->exec();
}
// 更新下载进度
void DownloadTask::updateProgress()
{
// 根据下载任务 id 更新 GUI 上的进度条
emit progress(this->id, bytesReceived, bytesTotal);
}
标签:int,void,QEventLoop,循环,线程,事件,qeventloop From: https://www.cnblogs.com/wish-sleeping/p/17402903.html