qt跨线程调用指定函数的几种方法

问题描述:

当前有两个线程,T1, T2;

线程T1的run函数中,实例化出来了对象O1(里面有work()函数),T2(UI线程,也叫主线程)的run中实例化出来了O2(里面有string widgetModify(xx)函数);

work()函数中想调用O2的str = widgetModify(xx)函数,这就是一个跨线程调用的例子,跨线程写widget,需要传入参数,而且还需要获得返回值。这应该怎么做呢?

答案:

如果work()函数中直接 str = O2->widgetModify(xx);

那就会报错了,因为跨线程操作UI界面,会造成和主线程同时修改同一个界面的风险,qt是不允许的

但是如果是去修改(写)主线程中对象的数据(非界面),是没问题的;

或者是去读取主线程中的对象的数据,包括界面,都是没问题的。

所以,正确的方式如下:

方法1:信号和槽

O1中设置一个信号,连接到O2的一个槽函数。O1发射该信号,O2的槽函数则被队列方式触发。

从而达到O1调用O2中的函数的目的。

本质:抛了一个事件给O2的队列里。

方法2:QMetaObject::invokeMethod

O1直接通过调用invokeMethod函数,用字符串方式指明要调用对方哪个函数。

本质:仍然是抛了一个事件给O2的队列里。

方法3:QTimer::singleShot() 

O1自己启动一个单词定时器singleShot,要执行的槽函数填对方。

本质:仍然是抛了一个事件给O2的队列里。

方法4:去直接发射主线程的信号

O2里自己定义一个信号,连接到自己的槽函数(连接类型填AutoConnection(或者不填,因为这是默认值),使用这个值则连接类型会在信号发送时qt自己决定)。

O1里直接发射O2对象的该信号,从而O2的槽函数得到执行。

这个多线程同时发射主线程的该信号,也是没问题的。

本质:虽然发射信号操作是在线程T1里执行,而且被发射的信号还是O2对象里的信号,但是发射后,其实自动是队列形式连接的O2的槽函数。

总结:

方法1是最容易想到的,但是写起来有点儿麻烦。方式4是最好用的(我自己想出来的方法),关键点在于别的对象可以发射别人的信号(跨线程也行),此外,跨线程没有同时操作界面的操作都是可以的)。

对了,关于获取返回值,我还没有研究,因为还没有这个需求。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt线程通信有多种方式,以下是常用的几种: 1. 信号与槽机制(Signal and Slot):是Qt最常用的线程通信方式。通过在一个对象定义一个信号,然后将其与其他对象的槽函数相连接,当信号被触发时,与之相连接的槽函数会被自动调用。这种方式可以线程通信,线程之间不需要直接进行函数调用。 2. 事件循环机制(Event Loop):每个线程Qt都有一个事件循环,通过在一个线程创建事件对象,然后将其发送给另一个线程的事件循环,被接收的线程会触发事件的处理函数。这种方式也支持线程通信。 3. 共享数据(Shared Data):通过在多个线程之间共享数据来实现线程通信。Qt提供了线程安全的数据结构,如QMutex、QReadWriteLock等,可以用来保证数据的安全访问。通过对共享数据的加锁和解锁操作即可实现线程之间的通信。 4. 直接调用(Direct Invocation):如果线程之间没有线程通信的需求,可以直接在一个线程调用一个线程函数Qt提供了QObject::invokeMethod()函数和QMetaObject::invokeMethod()函数来实现线程函数调用。 需要注意的是,在Qt线程之间的通信需要进行线程间同步和保护。Qt提供了一些工具类和函数来帮助实现线程安全的通信,如QMutex、QSemaphore等。在进行线程通信时,需要注意避免死锁和竞态条件等多线程编程常见的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值