【发布时间】:2021-07-02 19:26:53
【问题描述】:
我正在使用 python3.9-64,我需要创建一个 3d 立方体然后我按照这个tutorial, 我把程序分成了更多的文件,我使用 PyQt5 但教程使用 PyQt4,我更改了包含 calsses 的模块(例如:PyQt4 有 Gui.QMainWindow,PyQt5 有 QtWidgets.QMainWindow)
这是我的文件
core.py
cubeVtxList = [
[0.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 0.0, 1.0],
[1.0, 1.0, 1.0],
[0.0, 1.0, 1.0]]
cubeClrList = [
[1.0, 0.0, 0.0],
[1.0, 0.0, 0.0],
[1.0, 1.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0],
[1.0, 0.0, 1.0],
[1.0, 1.0, 1.0],
[0.0, 1.0, 1.0]]
cubeIdxList = [
0, 1, 2, 3,
3, 2, 6, 7,
1, 0, 4, 5,
2, 1, 5, 6,
0, 3, 7, 4,
7, 6, 5, 4 ]
GLWidget.py
from PyQt5.QtGui import QColor
from PyQt5.QtOpenGL import QGLWidget
import OpenGL.GL as gl
import OpenGL.GLU as glu
from OpenGL.arrays import vbo
import numpy as np
from core import *
class GLWidget(QGLWidget):
def __init__(self, parent=None):
self.parent = parent
QGLWidget.__init__(self)
def initializeGL(self):
self.qglClearColor(QColor(0, 0, 0))
gl.glEnable(gl.GL_DEPTH_TEST)
self.initGeometry()
self.rotX = 0.0
self.rotY = 0.0
self.rotZ = 0.0
def resizeGL(self, width, height):
gl.glViewport(0, 0, width, height)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
aspect = width / float(height)
glu.gluPerspective(45.0, aspect, 1.0, 100.0)
gl.glMatrixMode(gl.GL_MODELVIEW)
def paintGL(self):
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glPushMatrix()
gl.glTranslate(0.0, 0.0, -50.0) # third, translate cube to specified depth
gl.glScale(20.0, 20.0, 20.0) # second, scale cube
gl.glRotate(self.rotX, 1.0, 0.0, 0.0)
gl.glRotate(self.rotY, 0.0, 1.0, 0.0)
gl.glRotate(self.rotZ, 0.0, 0.0, 1.0)
gl.glTranslate(-0.5, -0.5, -0.5)
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glEnableClientState(gl.GL_COLOR_ARRAY)
gl.glVertexPointer(3, gl.GL_FLOAT, 0, self.vertVbo)
gl.glColorPointer(3, gl.GL_FLOAT, 0, self.colorVbo)
gl.glDrawElements(gl.GL_QUADS, len(self.cubeIdxArray), gl.GL_UNSIGNED_INT, self.cubeIdxArray)
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
gl.glDisableClientState(gl.GL_COLOR_ARRAY)
gl.glPopMatrix()
def initGeometry(self):
self.cubeVtxArray = np.array(cubeVtxList)
self.vertVbo = vbo.VBO(np.reshape(self.cubeVtxArray, (1, -1)).astype(np.float32))
self.vertVbo.bind()
self.cubeClrArray = np.array(cubeClrList)
self.colorVbo = vbo.VBO(np.reshape(self.cubeClrArray, (1, -1)).astype(np.float32))
self.colorVbo.bind()
self.cubeIdxArray = np.array(cubeIdxList)
def setRotX(self, val):
self.rotX = val
def setRotY(self, val):
self.rotY = val
def setRotZ(self, val):
self.rotZ = val
MWindow.py
from PyQt5.QtWidgets import QMainWindow, QSlider, QVBoxLayout, QWidget
from PyQt5 import QtCore
from GLWidget import GLWidget
from PyQt5.QtCore import QTimer
class MWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.resize(500, 500)
self.setWindowTitle('titolo')
self.glWidget = GLWidget(self)
self.initGui()
self.timer = QTimer()
self.timer.setInterval(20)
self.timer.timeout.connect(self.glWidget.updateGL)
self.timer.start()
def initGui(self):
central_widget = QWidget()
gui_layout = QVBoxLayout()
central_widget.setLayout(gui_layout)
self.setCentralWidget(central_widget)
gui_layout.addWidget(self.glWidget)
sliderX = QSlider(QtCore.Qt.Horizontal)
sliderX.valueChanged.connect(lambda val: self.glWidget.setRotX(val))
sliderY = QSlider(QtCore.Qt.Horizontal)
sliderY.valueChanged.connect(lambda val: self.glWidget.setRotY(val))
sliderZ = QSlider(QtCore.Qt.Horizontal)
sliderZ.valueChanged.connect(lambda val: self.glWidget.setRotZ(val))
gui_layout.addWidget(sliderX)
gui_layout.addWidget(sliderY)
gui_layout.addWidget(sliderZ)
main.py
from MWindow import MWindow
from PyQt5.QtWidgets import QApplication
import sys
def Main():
app = QApplication([])
mw = MWindow()
mw.show()
sys.exit(app.exec_())
if __name__ == '__main__':
Main()
结果应该是一个可以用滑块移动的立方体,但我得到了一个如下图所示的切割立方体
【问题讨论】:
标签: python opengl pyqt5 pyopengl python-3.9