首页 > 其他分享 >qeventloop 事件循环类

qeventloop 事件循环类

时间:2023-05-15 20:01:49浏览次数:32  
标签:int void QEventLoop 循环 线程 事件 qeventloop

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

相关文章

  • C#学习之time控件和timer_tick事件
    https://blog.csdn.net/ycigwy/article/details/70242669Timer控件:Timer控件只有绑定了Tick事件,和设置Enabled=True后才会自动计时,停止计时可以用Stop()控制,通过Stop()停止之后,如果想重新计时,可以用Start()方法来启动计时器。Timer控件和它所在的Form属于同一个线程;timer1_Tick:......
  • 基于门控循环单元GRU做多个特征变量输入,单个因变量输出的拟合预测建模。
    基于门控循环单元GRU做多个特征变量输入,单个因变量输出的拟合预测建模。程序内注释详细,可学习性强。程序直接替换数据就可以使用,不会替换数据的可以免费指导替换数据。程序语言是matlab的,需求版本是2020及以上。程序可以出真实值和预测值对比图,线性拟合图,可以打印多种评价指标,方便......
  • html绑定事件写法
    1.无参绑定<divonclick="onClick()"></div>2.传入源dom对象<divonclick="onClick(this)"></div>3.传入事件对象<divonclick="onClick(event)"></div>......
  • 监听容器中的文件系统事件
    基本概念Linux文件系统事件监听:应用层的进程操作目录或文件时,会触发systemcall,此时,内核中的notification子系统把该进程对文件的操作事件上报给应用层的监听进程(称为listerner)。dnotify:2001年的kernel2.4版本引入,只能监控directory,采用的是signal机制来向listener......
  • mouse事件
    mouse事件​ mousedown事件​ 事件在定点设备(如鼠标或触摸板)按钮在元素内按下时,会在该元素上触发​ 其是在按下那一刻触发​ mouseup事件​ 事件在定点设备(如鼠标或触摸板)按钮在元素内释放时,在该元素上触发​ mouseenter事件​ 事件在定点设备上(通常指鼠标)首次......
  • 23-5-14--循环控制结构--进化论
     在“一年一度喜剧大赛”上有一部作品《进化论》,讲的是动物园两只猩猩进化的故事。猩猩吕严说自己已经进化了9年了,因为“三年又三年”。猩猩土豆指出“三年又三年是六年呐”……本题给定两个数字,以及用这两个数字计算的结果,要求你根据结果判断,这是吕严算出来的,还是土豆算出来......
  • 事件循环机制
    事件循环是JavaScript的一种执行机制,用于协调异步任务的执行顺序、传递消息以及处理用户交互等事件。事件循环由以下四个组成部分组成。调用栈(CallStack):调用栈是JavaScript的一种执行机制,用于控制函数的执行顺序。当函数被调用时,将函数压入调用栈中,并开始执行函数,函数执行......
  • QAbstractEventDispatcher 抽象事件分发类
     QAbstractEventDispatcherQAbstractEventDispatcher是一个抽象事件分发类,提供了一个事件循环,并将事件分发给相应的对象。主要职责有:1.管理一个事件循环,接收各种事件并分发2.提供注册,注销事件等接口3.处理定时器,到期后触发timeout信号4.处理异步信号连接,将其包装为事件......
  • 【❂Java集合】循环链表和双向链表的区别是是什么
    最后一个结点指针指向不同在建立一个循环链表时,必须使其最后一个结点的指针指向表头结点,而不是像双向链表那样置为NULL。此种情况还用于在最后一个结点后插入一个新的结点。判断链域值不同在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值等于表头指针时,说明已到......
  • C基础笔记(for循环语句)
    循环之for语句从目一开始,连续不断做一件事,叫循环语法:for(表达式1(赋值语句初值);表达式2(条件);表达式3(增值的赋值语句)){ 循环要做的事(一次或多次)} #include<stdio.h>intmain(){ for(inti=1;i<=100;i++) { printf("%d\n",i); } retur......