当前位置: 首页 > ops >正文

QT异步操作

  • 高频调用时,singleShot(0) 会创建大量定时器事件

  • 推荐使用 invokeMethod 代替高频的 singleShot(0)

1.异步加载图片

    QTimer::singleShot(0, this, [this]() { Utils::Gui::LabelImageMax(ui.picture, ":/res/p1.png"); 
});//0:第一个参数是延迟时间(毫秒)。//0 表示不延迟,但实际执行是异步的(即不会立即阻塞当前线程执行)。//它会在当前事件循环的“下一个空闲时刻”立即执行(比非零延迟的优先级更高)。//this:第二个参数是接收者对象(QObject*)。//如果接收者在槽函数执行前被销毁,Qt 会安全地跳过调用(避免悬空指针问题)。//这里是 this,表示当前对象的生命周期控制回调的有效性。//[this]() {}:第三个参数是一个可调用对象(这里是一个 lambda 表达式)。//[this] 是 lambda 的捕获列表,表示捕获当前对象的指针(this),以便在 lambda 内访问成员变量或方//法。//() 是 lambda 的参数列表(此处无参数)。//{} 是 lambda 的函数体(此处为空,实际使用时会在其中添加具体逻辑)。
void QTimer::singleShot(int msec, const QObject *receiver, Functor functor)

这是 Qt 提供的一个静态方法,用于在指定的时间间隔后执行某个操作(单次触发,而不是周期性触发)。

执行时机

      在当前事件循环的下一个空闲时刻执行,比 invokeMethod 的队列优先级更高,总是在当前线程执行(除非指定其他线程的接收者)

// 危险!可能捕获临时对象
QTimer::singleShot(0, this, [this]() {useObject(obj); // obj可能已销毁
});// 安全做法:值捕获
auto safeObj = obj;
QTimer::singleShot(0, this, [this, safeObj]() {useObject(safeObj);
});

2.第二种异步

// 将数据处理移到主线程QMetaObject::invokeMethod(this, [this, data = opt.value()]() {processCoordinateMeasurement(data);});基本语法
bool QMetaObject::invokeMethod(QObject *obj,               // 目标对象const char *method,         // 方法签名Qt::ConnectionType type,    // 连接类型QGenericReturnArgument ret, // 返回值(可选)QGenericArgument val0 = QGenericArgument(), // 参数1QGenericArgument val1 = QGenericArgument(), // 参数2...                         // 更多参数
);

参数详解

1. 目标对象 (obj)

  • 必须是 QObject 或其子类的实例

  • 如果对象在执行前被销毁,调用会自动取消

  • 如果传入 nullptr,调用会被忽略(不会崩溃)

2. 方法签名 (method)

  • 格式:"methodName(type1,type2)"

  • 示例:"setValue(int)" 或 "calculate(QString,double)"

  • 可以使用 SIGNAL() 宏,但推荐直接使用字符串

  • 在 C++11 后,可以使用函数指针或 lambda

3. 连接类型 (type)

类型描述适用场景
Qt::AutoConnection默认类型,自动选择最佳连接方式通用场景
Qt::DirectConnection立即在当前线程调用同线程快速调用
Qt::QueuedConnection放入目标线程事件队列跨线程通信
Qt::BlockingQueuedConnection阻塞调用线程直到完成需要同步结果
Qt::UniqueConnection唯一连接,避免重复防止重复调

4. 返回值 (ret)

  • 用于获取方法返回值

  • 使用 Q_RETURN_ARG(type, variable) 宏

  • 仅适用于 DirectConnection 和 BlockingQueuedConnection

  • 异步调用通常不使用返回值

5. 参数 (val0, val1, ...)

  • 使用 Q_ARG(type, value) 宏传递参数

  • 最多支持 9 个参数

  • 参数类型必须是元对象系统认识的类型(基本类型或注册类型)

  • 1.// 调用无参方法
    QMetaObject::invokeMethod(button, "click", Qt::QueuedConnection);// 调用带参方法
    int value = 42;
    QMetaObject::invokeMethod(obj, "setValue", Qt::QueuedConnection, Q_ARG(int, value));2.示例 2: 带返回值调用
    QString result;
    QMetaObject::invokeMethod(calculator, "calculate", Qt::BlockingQueuedConnection,Q_RETURN_ARG(QString, result),Q_ARG(int, 5),Q_ARG(int, 7));
    qDebug() << "Result:" << result; // 输出计算结果

    lambda表达式

// 主线程更新UI
QMetaObject::invokeMethod(this, [this]() {statusLabel->setText("Processing complete");progressBar->setValue(100);
}, Qt::QueuedConnection);// 从工作线程传递数据到主线程
QImage processedImage = ...; // 在工作线程处理QMetaObject::invokeMethod(this, [this, processedImage]() {displayImage(processedImage); // 在主线程更新UI
}, Qt::QueuedConnection);

 3.总结:

  1. QMetaObject::invokeMethod 是更通用的跨线程通信工具,适合数据传递和线程间协作。

  2. QTimer::singleShot(0) 是同线程内延迟执行的优化方案,特别适合UI相关操作,有更高的执行优先级。

  3. 在纯主线程操作中,两者功能相似,但 singleShot(0) 通常有更直观的语义表示"尽快执行"。

  4. 关键选择因素:

    • 是否需要跨线程 → 选 invokeMethod

    • 是否传递复杂数据 → 选 invokeMethod

    • 是否UI紧急更新 → 选 singleShot(0)

    • 是否布局后操作 → 选 singleShot(0)

http://www.xdnf.cn/news/14769.html

相关文章:

  • Kuikly 与 Flutter 的全面对比分析,结合技术架构、性能、开发体验等核心维度
  • QT初识-实现Hello World(2)
  • Qt Quick 与 QML(五)qml中的布局
  • 运维打铁: 数据加密与备份恢复策略制定
  • 免费版安全性缩水?ToDesk、TeamViewer、向日葵、网易UU远程访问隐私防护测评
  • 【卡尔曼滤波第一期】α−β−γ 滤波器概述
  • [CS创世SD NAND征文] 精准控制的坚固基石:CS创世SD NAND在华大HC32F4A0运动控制卡中的高可靠应用
  • 如何在Excel中每隔几行取一行
  • Foundation 5 安装使用教程
  • 【仿muduo库实现并发服务器】Poller模块
  • Python应用指南:利用高德地图API获取公交+地铁可达圈(二)
  • UE5.6 官方文档笔记 [1]——虚幻编辑器界面
  • Qt_Creator入门基础知识
  • BFD故障检测技术之概述
  • 2025 推理技术风向标:DeepSeek-R1 揭示大模型从 “记忆” 到 “思考” 的进化路径
  • k8s将service的IP对应的不同端口分配到不同的pod上
  • day48
  • 【仿muduo库实现并发服务器】Connection模块
  • 630,百度文心大模型4.5系列开源!真香
  • mac python3.13 selenium安装使用
  • 半无界波动方程混合条件求解
  • 王道链表大题算法(部分)
  • 【记录】Word|Word创建自动编号的多级列表标题样式
  • 每日一练:找到初始输入字符串 I
  • 企业级应用技术-ELK日志分析系统
  • 矩阵的秩 线性代数
  • 具身多模态大模型在感知与交互方面的综述
  • RabbitMQ简单消息监听
  • MongoDB 安装使用教程
  • 我认知的AI宇宙系列第三期