gpt4 book ai didi

python - PySide2 QOpenGLWidget按键事件不起作用

转载 作者:行者123 更新时间:2023-12-01 06:27:32 26 4
gpt4 key购买 nike

据我了解,QOpenGlWidget 使用与任何其他小部件相同的窗口上下文。我认为使用 keyPressEvent 来处理绘图命令是个好主意。

不幸的是,它没有按预期工作。当我处理 Key_Escape 退出应用程序时,它可以工作,但是当我尝试处理 OpenGL 绘图函数的 Key_WKey_F 时,它不起作用不要 react 。

这是 GL 函数的问题还是我以错误的方式进行事件处理?

UPD:我还尝试在事件中更新小部件,它完全搞乱了屏幕上的所有内容。我对我的 GLFW 项目做了同样的事情,效果很好。

import numpy as np
from OpenGL.GL import *
from PySide2 import QtOpenGL, QtWidgets, QtCore, QtGui


class Viewport(QtWidgets.QOpenGLWidget):
def __init__(self, width: int, height: int, title :str="Qt OpenGl Window",
r: int=0.2, g: int=0.3, b: int=0.3, a: int=1.0):
super().__init__()
self.width = width
self.height = height
self.bg_color = (r, g, b, a)

self.setWindowTitle(title)
self.resize(self.width, self.height)

self.bool_shaded = True

self.vertices = np.array([], dtype=np.float32)

# Should be OpenGL.GL.shaders.ShaderProgram
self.shader_program = None
# Should be int to be used in "layout (location = attr_position)..."
self.attr_position = None

def initializeGL(self):

VBO = self.__createVBO(self.vertices)

# Create and bind here once because we have only one VAO that there's no need to bind every time
VAO = self.__createVAO()

self.shader_program = self.__compileShaders(path_vertex="shaders/triangle.vs",
path_fragment="shaders/triangle.fs")
self.attr_position = self.createAttribute(self.shader_program, "a_position", 0)

def paintGL(self):

glClear(GL_COLOR_BUFFER_BIT)
glClearColor(self.bg_color[0], self.bg_color[1],
self.bg_color[2], self.bg_color[3])
glUseProgram(self.shader_program)
glDrawArrays(GL_TRIANGLES, 0, 3)

def resizeGL(self, w: int, h: int):
glViewport(0, 0, w, h)

def keyPressEvent(self, event: QtGui.QKeyEvent):
if event.key() == QtCore.Qt.Key_Escape:
app.exit()

if event.key() == QtCore.Qt.Key_W:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)

if event.key() == QtCore.Qt.Key_F:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)

if event.key() == QtCore.Qt.Key_P:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)

event.accept()

def __createVBO(self, vertices :np.ndarray):

VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)

return VBO

def __createVAO(self):
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)

return VAO

def __compileShaders(self, path_vertex: str, path_fragment: str):
with open(path_vertex, "r") as source:
vertex = compileShader(source.read(), GL_VERTEX_SHADER)

with open(path_fragment, "r") as source:
fragment = compileShader(source.read(), GL_FRAGMENT_SHADER)

shader_program = compileProgram(vertex, fragment)

return shader_program

def createAttribute(self, shader, attrib_name: str, stride:
attribute = glGetAttribLocation(shader, attrib_name)
glEnableVertexAttribArray(attribute)
glVertexAttribPointer(attribute, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(0))

return attribute

def setVertices(self, vertex_list: list):
vertices = np.array(vertex_list, dtype=np.float32)
self.vertices = vertices

if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)

window = Viewport(1280, 720)

vertices = [-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0]
window.setVertices(vertices)

window.show()
window.printDebugInfo()

sys.exit(app.exec_())

最佳答案

在执行 OpenGL 指令之前,必须将 [OpenGL 上下文](OpenGL 上下文) 设置为当前。系统会在 paintGLresizeGL 之前自动将上下文设为当前上下文,但在 keyPressEvent 之前则不会。因此 keyPressEvent 中的 OpebGL 指令无效。

使用多边形模式的状态并在keyPressEvent中更改状态,但在paintGL中调用glPolygonMode来解决问题。例如:

class Viewport(QtWidgets.QOpenGLWidget):
# [...]

def initializeGL(self):

self.polygonmode = GL_FILL

# [...]

def paintGL(self):

glPolygonMode(GL_FRONT_AND_BACK, self.polygonmode)

# [...]

def keyPressEvent(self, event: QtGui.QKeyEvent):
if event.key() == QtCore.Qt.Key_Escape:
app.exit()

if event.key() == QtCore.Qt.Key_W:
self.polygonmode = GL_LINE

if event.key() == QtCore.Qt.Key_F:
self.polygonmode = GL_FILL

if event.key() == QtCore.Qt.Key_P:
self.polygonmode = GL_POINT

event.accept()

关于python - PySide2 QOpenGLWidget按键事件不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60061714/

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