惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
G
Google Developers Blog
V
V2EX
美团技术团队
H
Help Net Security
月光博客
月光博客
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
The Cloudflare Blog
U
Unit 42
大猫的无限游戏
大猫的无限游戏
Recent Announcements
Recent Announcements
A
About on SuperTechFans
博客园 - Franky
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
MyScale Blog
MyScale Blog
B
Blog
雷峰网
雷峰网
Y
Y Combinator Blog
云风的 BLOG
云风的 BLOG
T
The Blog of Author Tim Ferriss

博客园 - 朱小勇

C/C++导出库版本问题 高速互联常用概念 Anydoc使用 pyflow使用 两路 IQ 复数相除 minizip使用 解决Qt无法cdb调试问题 使用zadig-安装winusb驱动 libusb编译 word设置表和图的自动编号 DAC、AOC、AEC、ACC说明 技能包:qtwidget-instrument-control SKILL技能包学习 T参数 Python查看某个库版本并更新 C++通过pybind11与Python互调 数字信号处理-C++开源库 C++实现窗函数 C++-FFTW C++-Eigen SI-python工程参考 PAM4相关概念 win11共享文件夹 Qt使用QSplashScreen实现软件启动过渡界面 QGroundControl 建议尺寸 封窗知识 网分的触发学习 豆包生成图片去除水印 matlabe东向偏移、北向偏移、垂直偏移转经纬度
Qt通信架构
朱小勇 · 2026-08-25 · via 博客园 - 朱小勇

1、模块件采用单例,直接访问对方的接口,接口尽量采用同步设计,所以调用方需要在线程中调用接口

2、模块内部采用invoke访问工作线程的接口

3、invoke封装

///> 异步调用拉姆达
template <typename Func>
bool invokeAsync(QObject* obj, Func&& func) {
    if (!obj) {QLOG_ERROR()<<"invokeAsync failed, obj is null";return false;}
    return QMetaObject::invokeMethod(obj, std::forward<Func>(func), Qt::QueuedConnection);            //直接返回, 异步执行func
}

///> 同步调用拉姆达
template <typename Func>
bool invokeSync(QObject* obj, Func&& func) {
    if (!obj) {QLOG_ERROR()<<"invokeSync failed, obj is null";return false;}
    if (obj->thread() == QThread::currentThread()) {
        return QMetaObject::invokeMethod(obj, std::forward<Func>(func), Qt::DirectConnection);        //直接调用阻塞fun执行完成
    } else {
        return QMetaObject::invokeMethod(obj, std::forward<Func>(func), Qt::BlockingQueuedConnection);//当前线程阻塞, 等待obj线程执行fun完成
    }
}

///> 异步调用函数指针
template <typename Func, typename... Args>
bool invokeAsync(QObject* obj, Func&& func, Args&&...args) {
    if (!obj) {QLOG_ERROR()<<"invokeAsync failed, obj is null";return false;}
    return QMetaObject::invokeMethod(obj, func, Qt::QueuedConnection, std::forward<Args>(args)...);
}

///> 同步调用函数指针, 带返回值
template <typename Func, typename Ret, typename... Args>
bool invokeSync(QObject* obj, Func&& func, Ret& ret, Args&&...args) {
    if (!obj) {QLOG_ERROR()<<"invokeSync failed, obj is null";return false;}
    if (obj->thread() == QThread::currentThread()) {
        return QMetaObject::invokeMethod(obj, func, Qt::DirectConnection, Q_RETURN_ARG(Ret, ret), std::forward<Args>(args)...);
    } else {
        return QMetaObject::invokeMethod(obj, func, Qt::BlockingQueuedConnection, Q_RETURN_ARG(Ret, ret), std::forward<Args>(args)...);
    }
}

///> 同步调用函数指针, 不带返回值
template <typename Func, typename... Args>
bool invokeSync(QObject* obj, Func&& func, Args&&...args) {
    if (!obj) {QLOG_ERROR()<<"invokeSync failed, obj is null";return false;}
    if (obj->thread() == QThread::currentThread()) {
        return QMetaObject::invokeMethod(obj, func, Qt::DirectConnection, std::forward<Args>(args)...);
    } else {
        return QMetaObject::invokeMethod(obj, func, Qt::BlockingQueuedConnection, std::forward<Args>(args)...);
    }
}