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

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
B
Blog RSS Feed
大猫的无限游戏
大猫的无限游戏
博客园_首页
雷峰网
雷峰网
V
Visual Studio Blog
爱范儿
爱范儿
A
About on SuperTechFans
量子位
N
Netflix TechBlog - Medium
Microsoft Security Blog
Microsoft Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
S
SegmentFault 最新的问题
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - keleman

lambda 如何捕获 所在子线程ID 配置 git 到达 通过 git &&ssh 登录 gitee.com 和 github.com 整理于豆包问答,测试可以实现 由QThread::currentThread()引出的 如何在线程中安全运行任务 由豆包整理的 持有 std::unique_ptr 的 lambda → 不能放进 std::function 从豆包整理 C++ Lambda 捕获方式・安全写法速查表 整理自豆包 C++14 Lambda 相比 C++11 的核心改进 firefox 149 在 linux mint 21 上的 mozillia 源安装 qt GUI 如何利用q thread 和qfuturwatcher 实现 不阻塞主线程? xargs 和管道 |的区别 一加5t的volte怎么设置 做上位机软件设计 下位机软件设计 以二级指针作为函数参数,并从函数中分配空间的原理 std::forward<T> ,std::move 使用场景的区别 VS2017 设置 类模板参数推导(CTAD, Class Template Argument Deduction) postEvent 和 sendEvent的区别 QObject Event( )customEvent( ) 函数区别 关于实际项目中必要的几个文件操作接口 QwaitCondition.的工作原理 【Debian】更换软件 源出现的Certificate问题解决方法 linux PS1 提示符的颜色设置 python 的几个常用的函数 知识点 设置 docker 国内的 映像加速器 docker 容器安装软件 docke 容器设置代理 docker 安装问题
qt 将槽函数在子线程中执行的方法
keleman · 2025-04-21 · via 博客园 - keleman

通过信号槽机制

对象A通过信号sginal1链接 子线程的成员对象B的槽函数slot1。
则 emit sginal1 后会在子线程中调用槽函数1
伪代码
Qthread b;
B.movethread(&b);
connect(&A,SIGNAL(XXX()),&B,SLOT(YYY()));

通过 QMetaObject::InvokedMethod(...) 直接调用 子线程的成员变量槽函数,或用 Q_INVOKABLE 标识的函数。

下面对第二种方法 介绍

被调函数必须是槽函数 或 Q_INVOKABL表示的函数

invokedMethod原型:

bool QMetaObject::invokeMethod(
QObject *obj,
const char *method,
Qt::ConnectionType type,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(nullptr),
QGenericArgument val1 = QGenericArgument(),
...
);
调用示例:

1传递基本类型参数

// 目标方法(在某个 QObject 派生类中)
Q_INVOKABLE void myMethod(int num, const QString &text);

// 调用代码
int value = 42;
QString text = "Hello";
QMetaObject::invokeMethod(
obj,
"myMethod",
Qt::AutoConnection,
Q_ARG(int, value),
Q_ARG(QString, text)
);

需要先注册自定义类型到 Qt 的元类型系统:

步骤 1:使用 Q_DECLARE_METATYPE

// 在头文件中声明自定义类型
struct MyCustomType {
int id;
QString name;
};
Q_DECLARE_METATYPE(MyCustomType)

步骤 2:注册类型(通常在 main 函数)

qRegisterMetaType("MyCustomType");

步骤 3:传递自定义类型参数

// 目标方法
Q_INVOKABLE void handleCustomType(const MyCustomType &data);

// 调用代码
MyCustomType data;
data.id = 1;
data.name = "Test";
QMetaObject::invokeMethod(
obj,
"handleCustomType",
Qt::AutoConnection,
Q_ARG(MyCustomType, data)
);

3. 处理返回值

如果方法有返回值,使用 Q_RETURN_ARG 捕获:

// 目标方法
Q_INVOKABLE int calculate(int a, int b);

// 调用代码
int result;
QMetaObject::invokeMethod(
obj,
"calculate",
Qt::DirectConnection,
Q_RETURN_ARG(int, result),
Q_ARG(int, 3),
Q_ARG(int, 5)
);
qDebug() << "Result:" << result; // 输出 8

4. 异步调用(跨线程)

指定 Qt::QueuedConnection 进行异步调用:

QMetaObject::invokeMethod(
obj,
"updateUI",
Qt::QueuedConnection,//*****************88
Q_ARG(QString, "New Text")
);

就不用添加很多的 信号槽链接了