PySide6+Qt3D中Error 0x80070057(参数不正确)的解决方法
Qt3D绘制直线报错:Failed to create input layout 解决方法
问题描述
运行绘制单条直线的PySide6 Qt3D代码时,出现以下错误:
Qt3D.Renderer.RHI.Backend: Initializing RHI with DirectX backend Failed to create input layout: Error 0x80070057: The parameter is incorrect. Qt3D.Renderer.RHI.Backend: Failed to build graphics pipeline: Creation Failed
可正常运行Qt3D官方简单3D示例,也能修改加载.stl文件,但所有使用QGeometryRenderer绘制直线的代码变体均报相同错误。
平台信息:Win10 x64、Python 3.11.4、PySide6 6.4.2
复现代码:
import struct import sys from PySide6.QtCore import (QByteArray) from PySide6.QtGui import (QGuiApplication, QVector3D) from PySide6.Qt3DCore import (Qt3DCore) from PySide6.Qt3DExtras import (Qt3DExtras) from PySide6.Qt3DRender import (Qt3DRender) class Line(Qt3DCore.QEntity): def __init__(self, parent=None, start=QVector3D(0.0, 0.0, 0.0), end = QVector3D(10.0, 0.0, 0.0)): super().__init__(parent) self.start = start self.end = end self.geometry = Qt3DCore.QGeometry(self) # 创建顶点缓冲区数据 points = QByteArray() points.append(struct.pack('f', start.x())) points.append(struct.pack('f', start.y())) points.append(struct.pack('f', start.z())) points.append(struct.pack('f', end.x())) points.append(struct.pack('f', end.y())) points.append(struct.pack('f', end.z())) self.vertexBuffer = Qt3DCore.QBuffer(self.geometry) self.vertexBuffer.setData(points) # 创建顶点属性 attribute = Qt3DCore.QAttribute(self.geometry) attribute.setName(Qt3DCore.QAttribute.defaultPositionAttributeName()) attribute.setVertexBaseType(Qt3DCore.QAttribute.VertexBaseType.Float) attribute.setVertexSize(3) attribute.setAttributeType(Qt3DCore.QAttribute.AttributeType.VertexAttribute) attribute.setBuffer(self.vertexBuffer) attribute.setByteOffset(0) attribute.setByteStride(3 * 4) attribute.setCount(2) self.geometry.addAttribute(attribute) # 创建渲染器 self.renderer = Qt3DRender.QGeometryRenderer() self.renderer.setPrimitiveType(Qt3DRender.QGeometryRenderer.Lines) self.renderer.setGeometry(self.geometry) self.addComponent(self.renderer) class Window(Qt3DExtras.Qt3DWindow): def __init__(self): super().__init__() self.camera().lens().setPerspectiveProjection(45, 16 / 9, 0.1, 1000) self.camera().setPosition(QVector3D(0, 0, 10)) self.camera().setViewCenter(QVector3D(0, 0, 0)) self.rootEntity = Qt3DCore.QEntity() self.material = Qt3DExtras.QPhongMaterial(self.rootEntity) self.line = Line(self.rootEntity) self.line.addComponent(self.material) self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity) self.camController.setLinearSpeed(50) self.camController.setLookSpeed(180) self.camController.setCamera(self.camera()) self.setRootEntity(self.rootEntity) if __name__ == '__main__': app = QGuiApplication(sys.argv) view = Window() view.show() sys.exit(app.exec())
解决方案
问题核心是顶点缓冲区QBuffer未被显式创建,导致GPU无法访问顶点数据,进而触发输入布局构建失败。只需在设置缓冲区数据后调用create()方法即可修复。同时,建议明确指定字节序以提升跨平台兼容性。
修改后的Line类代码如下:
class Line(Qt3DCore.QEntity): def __init__(self, parent=None, start=QVector3D(0.0, 0.0, 0.0), end = QVector3D(10.0, 0.0, 0.0)): super().__init__(parent) self.start = start self.end = end self.geometry = Qt3DCore.QGeometry(self) # 创建顶点数据,明确指定小端字节序 points = bytearray() points += struct.pack('<fff', start.x(), start.y(), start.z()) points += struct.pack('<fff', end.x(), end.y(), end.z()) # 初始化顶点缓冲区并指定类型 self.vertexBuffer = Qt3DCore.QBuffer(Qt3DCore.QBuffer.VertexBuffer, self.geometry) self.vertexBuffer.setData(QByteArray(points)) # 关键:创建缓冲区,让GPU能访问数据 self.vertexBuffer.create() # 配置顶点属性 attribute = Qt3DCore.QAttribute(self.geometry) attribute.setName(Qt3DCore.QAttribute.defaultPositionAttributeName()) attribute.setVertexBaseType(Qt3DCore.QAttribute.VertexBaseType.Float) attribute.setVertexSize(3) attribute.setAttributeType(Qt3DCore.QAttribute.AttributeType.VertexAttribute) attribute.setBuffer(self.vertexBuffer) attribute.setByteOffset(0) attribute.setByteStride(3 * 4) attribute.setCount(2) self.geometry.addAttribute(attribute) # 配置渲染器 self.renderer = Qt3DRender.QGeometryRenderer() self.renderer.setPrimitiveType(Qt3DRender.QGeometryRenderer.Lines) self.renderer.setGeometry(self.geometry) self.addComponent(self.renderer)
补充说明
- 官方示例和STL加载场景中,Qt3D内部已自动处理缓冲区创建逻辑,因此无需手动调用
create()。 - 错误码
0x80070057表示参数错误,本质是后端无法获取有效顶点数据,导致输入布局构建失败。
内容的提问来源于stack exchange,提问作者Ross
相关产品推荐
相关产品推荐

