QQuick提供了丰富的控件,搭配qml很容易就可以搭配出一套丝滑的UI界面。但是在有些场景下无论是出于效率还是现有控件的局限都需要进行自绘才能实现自身的需求。QQuick支持多种自绘:
可以使用的方案:
1. 继承QQuickPaintedItem ,重写 paint 函数
优点: 这个是最容易实现的方式,也非常贴合QWidget那一套方案,QPainter自绘的接口也是一样的,无学习成本。底层会根据操作转换为对应的OpenGL渲染。即不需要学习OpenGL的api也能享受到OpenGL用GPU渲染的好处
代价: renderTarget==QQuickPaintedItem::Image 在这个模式下,会有一层纹理数据的copy,性能上会有损失
2. 继承QQuickFrameBufferObject,重写 createRenderer 函数
createRenderer函数需要返回一个QQuickFramebufferObject::Renderer对象,自绘操作是在QQuickFramebufferObject::Renderer::render操作中进行的,这里面可以用OpenGL进行绘制操作
优点: 性能好,直接用OpenGL绘制,省去了纹理的copy操作
代价: 需要学习OpenGL相关知识
3. 继承QQuickItem,重写 updatePaintNode
这种方法更直接,因为QQuick所有的可视元素都是继承QQuickItem,渲染的根本就是每一次update时调用每一个可视QQuickItem的updatePaintNode收集要渲染的内容,上面两种方式其实就是QQuick框架在内部定义好了 updatePaintNode 逻辑
优点: 性能好,省去了中间的其他转换逻辑,内部可以根据当前框架所使用的渲染方式(OpenGL、D3D\Metal(MAC)\Soft),来决定使用哪一套绘制方案。
代价: 需要学习更多关于本地绘制的api使用方法(OpenGL/D3D/Metal/Soft)
ps:指定QQuick使用那一套渲染框架: enum GraphicsApi {Unknown,Software,OpenGL,Direct3D12,OpenVG,OpenGLRhi,Direct3D11Rhi,VulkanRhi,MetalRhi,NullRhi,};QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);