gpt4 book ai didi

python - 当我没有为 openGLWidget 创建额外的类时,为什么 glRotate 只工作一次?

转载 作者:行者123 更新时间:2023-12-01 07:08:06 33 4
gpt4 key购买 nike

我正在编写一个 GUI,用于使用 Python 显示 6 轴运动传感器的输出。窗口应该有一个实时显示旋转的 OpenGL Widget。通常我会为我的 openGLWidget 编写一个单独的类,但由于我的 UI 有相当多的元素,从头开始构建它似乎不合理。相反,我只是加载 .ui 文件,找到我需要的一切,仅此而已。然而,glRotate()函数只更新一次,然后就不再更新了,我不知道是什么导致了这个问题。

from PyQt5 import QtWidgets, uic
from PyQt5.QtCore import *
import OpenGL.GL as gl
import OpenGL.GLU as glu
import sys


class Ui(QtWidgets.QWidget):
def __init__(self):
super(Ui, self).__init__()
uic.loadUi('gl_test.ui', self)

self.openGLWidget = self.findChild(QtWidgets.QOpenGLWidget, 'openGLWidget')
self.openGLWidget.initializeGL()
self.openGLWidget.paintGL = self.paintGL
self.openGLWidget.initializeGL = self.initializeGL
self.object = None

self.rotation = 45.0

# QTimer for updating the GL Viewport
self.GLtimer = QTimer()
self.GLtimer.setInterval(100)
self.GLtimer.timeout.connect(self.openGLWidget.paintGL)
self.GLtimer.start()

def paintGL(self):
try:
gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
x, y, width, height = gl.glGetDoublev(gl.GL_VIEWPORT)
glu.gluPerspective(
45, # field of view in degrees
width / float(height or 1), # aspect ratio
.25, # near clipping plane
200, # far clipping plane
)
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glLoadIdentity()
gl.glTranslated(0.0, 0.0, -10.0)
self.rotation += 1
print(self.rotation)
gl.glRotate(self.rotation, 1, 0, 0) # works only once for some reason?
gl.glCallList(self.object)
except Exception as exc:
print(exc)
pass

def initializeGL(self):
try:
# making an example cube
self.object = gl.glGenLists(1)
gl.glNewList(self.object, gl.GL_COMPILE)
gl.glBegin(gl.GL_QUADS)

gl.glColor3f(0.0, 1.0, 0.0)
gl.glVertex3f(1.0, 1.0, -1.0)
gl.glVertex3f(-1.0, 1.0, -1.0)
gl.glVertex3f(-1.0, 1.0, 1.0)
gl.glVertex3f(1.0, 1.0, 1.0)

gl.glColor3f(0.0, 1.0, 0.0)
gl.glVertex3f(1.0, -1.0, 1.0)
gl.glVertex3f(-1.0, -1.0, 1.0)
gl.glVertex3f(-1.0, -1.0, -1.0)
gl.glVertex3f(1.0, -1.0, -1.0)

gl.glColor3f(0.0, 1.0, 0.0)
gl.glVertex3f(1.0, 1.0, 1.0)
gl.glVertex3f(-1.0, 1.0, 1.0)
gl.glVertex3f(-1.0, -1.0, 1.0)
gl.glVertex3f(1.0, -1.0, 1.0)

gl.glColor3f(0.0, 1.0, 0.0)
gl.glVertex3f(1.0, -1.0, -1.0)
gl.glVertex3f(-1.0, -1.0, -1.0)
gl.glVertex3f(-1.0, 1.0, -1.0)
gl.glVertex3f(1.0, 1.0, -1.0)

gl.glColor3f(0.0, 1.0, 0.0)
gl.glVertex3f(-1.0, 1.0, 1.0)
gl.glVertex3f(-1.0, 1.0, -1.0)
gl.glVertex3f(-1.0, -1.0, -1.0)
gl.glVertex3f(-1.0, -1.0, 1.0)

gl.glColor3f(0.0, 1.0, 0.0)
gl.glVertex3f(1.0, 1.0, -1.0)
gl.glVertex3f(1.0, 1.0, 1.0)
gl.glVertex3f(1.0, -1.0, 1.0)
gl.glVertex3f(1.0, -1.0, -1.0)

gl.glEnd()
gl.glEndList()

gl.glEnable(gl.GL_CULL_FACE)
except Exception as exc:
print(exc)
pass


def main():
app = QtWidgets.QApplication(sys.argv)
window = Ui()
window.show()
app.exec_()


main()

.ui file code

这是不起作用的部分。随着每次 paintGl() 增加 self.rotation 并因此调用 glRotate() ,我希望立方体能够旋转,但由于某种原因它没有旋转。

最佳答案

问题是计时器事件:

self.GLtimer.timeout.connect(self.openGLWidget.paintGL)

不建议直接调用.paintGL。请注意,OpenGL 无法绘制任何内容,OpenGL Context必须在绘制之前和之后将其设置为当前,必须更新窗口。您可以看到初始绘图,因为对 .paintGL 的第一次调用是由框架完成的。由计时器事件发起的以下调用不会生成有效的输出。您必须调用.update() ,这使得上下文成为当前上下文并触发 .paintGL() 被调用,例如:

class Ui(QtWidgets.QWidget):
def __init__(self):

# [...]

self.GLtimer = QTimer()
self.GLtimer.setInterval(100)
self.GLtimer.timeout.connect(self.redraw)
self.GLtimer.start()

def redraw(self):
# updated the widget - triggers paintGL to be called
self.openGLWidget.update()

动画是你原来的代码生成的,只不过我已经通过 glPolygonMode 切换到画线模式了。

gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)

关于python - 当我没有为 openGLWidget 创建额外的类时,为什么 glRotate 只工作一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58346974/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com