我可以在QThread中使用与QAbstractTableModel数据的交互吗?



我知道我们不能在非 GUI 线程中使用 GUI 交互(QThread )。但我不知道我们是否可以在线程中与模型(QAbstractItemModel)交互,如果为 True,那么如何以正确的方式做到这一点?

老实说,我在谷歌和 SO 上搜索了一些关于这个的东西,似乎我的问题没有相关的答案。

"与模型交互"是什么意思?如果您的意思是要通过直接操作模型从多个线程访问模型,则必须序列化对模型的访问。由于模型中有很多方法,我建议您不要在模型中添加互斥锁 - 这将非常乏味且容易出错,因为很容易忘记互斥锁。相反,请使用模型继承 QObject 的事实,因此可以接受事件。

  1. 您的 gui 线程直接访问模型。
  2. 其他线程通过向模型发布事件(并可能接收回复事件)与模型交互。
  3. gui 线程将使用任何其他访问串行处理这些事件,从而保护您的模型免受并发访问。

其他线程当然可以从模型接收回复 - 也可以通过事件。您将有两个事件基类:一个用于从模型请求内容的Request类,然后有一个模型将用于回复的Response事件基类。Request 类应具有QObject* sender成员,以便模型知道要将回复事件发布到哪个 QObject。您可能希望请求和回复都带有相同的标识符(例如串行递增 int),以便请求和响应可以匹配。

你必须实现所有通过事件与模型交互的线程代码,而不是通过重新实现QThread::run(),而是在QObject中。实例化QObject后,只需将其移动到单独的线程即可。QThread的默认run()实现将旋转一个事件循环,以保持您的QObject在有任何事件,信号或计时器准备就绪时执行。零持续时间计时器是一种使线程永久繁忙的方法,但请确保不要一次性进行太多处理,否则会延迟对传入事件的处理。

您也可以使用信号和插槽,但不能直接调用它们,只能:

  1. 对他们connect()
  2. 通过带有Qt::QueuedConnectionQMetaObject::invokeMethod调用它们。
  3. 通过在主线程上下文中执行的函子(例如 lambda)调用它们;有关如何执行此操作,请参阅此答案。

在后台,当您将信号连接到驻留在单独线程中的 QObject 插槽时,Qt 会创建一个连接,将每个信号封送到一个QMetaCallEvent中,然后在具有目标插槽的 QObject 所在的线程中解组。

相关内容

  • 没有找到相关文章

最新更新