pyqt openglwidget中实现旋转缩放移动操作示例
时间: 2023-05-16 16:06:39 浏览: 243
可以使用QOpenGLWidget和QOpenGLFunctions类来实现旋转、缩放和移动操作。以下是一个示例代码:
```python
from PyQt5.QtWidgets import QApplication, QOpenGLWidget
from PyQt5.QtGui import QOpenGLShader, QOpenGLShaderProgram, QOpenGLVertexArrayObject, QOpenGLBuffer
from PyQt5.QtCore import QSize, Qt, QPoint, QPointF
from PyQt5.QtGui import QVector3D, QMatrix4x4
import numpy as np
class OpenGLWidget(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.vertices = np.array([
[-0.5, -0.5, 0.0],
[0.5, -0.5, 0.0],
[0.0, 0.5, 0.0]
], dtype=np.float32)
self.colors = np.array([
[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0]
], dtype=np.float32)
self.vao = None
self.vbo = None
self.shader_program = None
self.model_matrix = QMatrix4x4()
self.view_matrix = QMatrix4x4()
self.projection_matrix = QMatrix4x4()
self.last_pos = QPoint()
def initializeGL(self):
self.initializeOpenGLFunctions()
self.createShaders()
self.createBuffers()
self.vao = QOpenGLVertexArrayObject(self)
self.vao.create()
self.vao.bind()
self.shader_program.enableAttributeArray(0)
self.shader_program.setAttributeBuffer(0, Qt.AlignLeft, 0, 3, 0)
self.shader_program.enableAttributeArray(1)
self.shader_program.setAttributeBuffer(1, Qt.AlignLeft, self.vertices.nbytes, 3, 0)
self.vao.release()
self.shader_program.release()
def createShaders(self):
vertex_shader = QOpenGLShader(QOpenGLShader.Vertex, self)
vertex_shader_source = """
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 ourColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
ourColor = aColor;
}
"""
vertex_shader.compileSourceCode(vertex_shader_source)
fragment_shader = QOpenGLShader(QOpenGLShader.Fragment, self)
fragment_shader_source = """
#version 330 core
in vec3 ourColor;
out vec4 FragColor;
void main()
{
FragColor = vec4(ourColor, 1.0);
}
"""
fragment_shader.compileSourceCode(fragment_shader_source)
self.shader_program = QOpenGLShaderProgram(self)
self.shader_program.addShader(vertex_shader)
self.shader_program.addShader(fragment_shader)
self.shader_program.link()
def createBuffers(self):
self.vbo = QOpenGLBuffer(QOpenGLBuffer.VertexBuffer)
self.vbo.create()
self.vbo.bind()
self.vbo.allocate(self.vertices.nbytes + self.colors.nbytes)
self.vbo.write(0, self.vertices.tobytes())
self.vbo.write(self.vertices.nbytes, self.colors.tobytes())
self.vbo.release()
def resizeGL(self, width, height):
self.projection_matrix.setToIdentity()
self.projection_matrix.perspective(45.0, width / height, 0.1, 100.0)
def paintGL(self):
self.glClearColor(0.2, 0.3, 0.3, 1.0)
self.glClear(self.GL_COLOR_BUFFER_BIT | self.GL_DEPTH_BUFFER_BIT)
self.vao.bind()
self.shader_program.bind()
self.shader_program.setUniformValue("model", self.model_matrix)
self.shader_program.setUniformValue("view", self.view_matrix)
self.shader_program.setUniformValue("projection", self.projection_matrix)
self.glDrawArrays(self.GL_TRIANGLES, 0, 3)
self.shader_program.release()
self.vao.release()
def mousePressEvent(self, event):
self.last_pos = event.pos()
def mouseMoveEvent(self, event):
dx = event.x() - self.last_pos.x()
dy = event.y() - self.last_pos.y()
if event.buttons() & Qt.LeftButton:
self.model_matrix.rotate(dy, QVector3D(1, 0, 0))
self.model_matrix.rotate(dx, QVector3D(0, 1, 0))
self.update()
elif event.buttons() & Qt.RightButton:
self.model_matrix.translate(dx / 100.0, -dy / 100.0, 0)
self.update()
elif event.buttons() & Qt.MiddleButton:
self.model_matrix.translate(0, 0, dy / 100.0)
self.update()
self.last_pos = event.pos()
def wheelEvent(self, event):
delta = event.angleDelta().y() / 120.0
self.model_matrix.scale(1 + delta / 10.0)
self.update()
if __name__ == '__main__':
app = QApplication([])
widget = OpenGLWidget()
widget.resize(800, 600)
widget.show()
app.exec_()
```
这个示例代码实现了一个三角形的绘制,并且支持旋转、缩放和移动操作。可以通过鼠标左键旋转,右键平移,中键移动视角,滚轮缩放。
阅读全文