Насколько я понимаю, QOpenGlWidget
использует тот же контекст окна, что и любой другой виджет. Я подумал, что было бы неплохо использовать keyPressEvent
для обработки команд рисования.
К сожалению, это не работает должным образом. Когда я обрабатываю Key_Escape
для выхода из приложения, он работает, но когда я пытаюсь обработать Key_W
или Key_F
для функций рисования OpenGL, он не реагирует.
Это проблема с Функции 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_())