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

标签 qt qt4 qthread qabstractitemmodel qabstracttablemodel

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

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

最佳答案

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

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

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

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

    你也可以使用信号和槽,但是你不能直接调用它们,你只能:
  • connect()给他们,
  • 通过 QMetaObject::invokeMethod 调用它们与 Qt::QueuedConnection .
  • 通过在主线程上下文中执行的仿函数(例如 lambda)调用它们;见 this answer如何做到这一点。

  • 在幕后,当您将信号连接到驻留在不同线程中的 QObject 插槽时,Qt 会创建一个连接,将每个信号编码到 QMetaCallEvent 中。 ,然后在具有目标插槽的 QObject 所在的线程中解码它。

    关于qt - 我可以在 QThread 中使用与 QAbstractTableModel 数据的交互吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10223012/

    相关文章:

    Qt 人工鼠标点击不能正常工作

    c++ - QThread::wait() 不使用直接连接不返回

    python - PySide2 Qthread 崩溃

    c++ - 将滚动条与 QGridLayout 一起使用

    python - 如何使用 pyqt 在场景中输出颜色图?

    Qt:将原始 QAudioInput 数据写入文件的 API,就像 QAudioRecorder 一样

    multithreading - QProgressBar 不显示进度?

    c++ - 为什么这个简单的 Qt 应用程序没有链接

    qt - 将插槽添加到自动创建的菜单项

    python - pyqtgraph ImageView 在多线程时卡住