【发布时间】:2021-01-05 17:34:54
【问题描述】:
我们有在渲染线程中执行的命令队列,直接在QQuickWindow::beforeRendering 和QQuickWindow::afterRendering 之间,命令对数据模型进行更改,当数据模型发生更改时,它会立即通知我们的自定义 OpenGL 渲染引擎同步数据。
问题在于,当数据模型发生变化时,它也会通知打算更新 UI 的订阅者。
但是从不同的线程更新 UI 是容易出错的方法。一种方法是使用Qt::QueuedConnection。这也容易出错,因为执行时模型可能会进入远状态。
设计与example非常相似。
是否可以从渲染线程更新与 QML 链接的 QStadardItemModel?
【问题讨论】:
-
为什么在渲染 UI 时执行命令?只是不要那样做。渲染应该只使用当前数据/状态绘制 UI,而不是更改任何数据/状态。
-
因为命令可能会导致渲染器状态的变化。例如,我们有命令 AddBoxCommand。执行此命令时,它会通知渲染器添加的新对象,渲染器通过更改其状态来对此事件做出反应。渲染器直接在
beforeRendering和afterRendering之间工作,所以我们不能在他工作时从不同的线程改变他的状态。 Windows 上的 Qt Quick 使用线程渲染循环,因此渲染线程永远不会锁定。主(Gui)线程通过锁定自己来启动与渲染线程的同步。主线程保持锁定,而渲染线程仍在工作。 -
我们希望渲染器在 Qt Quick 的渲染线程中完成他的工作,因为 OpenGL 上下文共享可能存在问题。这就是我们在
beforeRendering和afterRendering之间注入命令执行的原因。
标签: c++ multithreading qt opengl qml