Search code examples
pythonpython-3.xpyqtpyqt5pyopengl

Loop for key input who modifies OpenGL wigdet


I am trying to create a loop who is being executed all time and checks for key input. This loop would modify the OpenGL properties, but I do not know how to create it. I think I have to overrid a method, but I do not know which. I have created two classes, one for the main window which does not overrid anything, and other one for the OpenGL widget, who overrides a QOpenGLWidget and uses (and overrides) the initializeGL and paintGL methods.

Code:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QOpenGLWidget
from OpenGL.GL import *
from OpenGL.GLU import *
import sys

class Render(QOpenGLWidget):
    def initializeGL(self):
        glClear(GL_COLOR_BUFFER_BIT)
        self.vertices_v = [
            [1, 1, 0],
            [1, -1, 0],
            [-1, -1, 0],
            [-1, 1, 0]
        ]
        self.vertices_h = [
            [1, 0, -1],
            [1, 0, 1],
            [-1, 0, 1],
            [-1, 0, -1]
        ]
        glEnable(GL_DEPTH_TEST)
        gluPerspective(60, 750 / 1000, 1, 30)
        glTranslatef(0, -0.5, -1.5)

    def paintGL(self):
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR)
        glBegin(GL_QUADS)
        glColor4fv((0, 1, 0, 0.6))
        for vertex in range(4):
            glVertex3fv(self.vertices_v[vertex])
        glColor4fv((1, 0, 0, 0.6))
        for vertex in range(4):
            glVertex3fv(self.vertices_h[vertex])
        glEnd()
        glDisable(GL_BLEND)

class UiVentana:
    def __init__(self):
        ventana.resize(1250, 750)
        ventana.setLayoutDirection(QtCore.Qt.LeftToRight)
        ventana.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
        self.widget_central = QtWidgets.QWidget(ventana)
        self.gridLayoutWidget = QtWidgets.QWidget(self.widget_central)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(1000, 0, 251, 55))

        # More UI stuff

        self.Visor = Render(self.widget_central)
        self.Visor.setGeometry(QtCore.QRect(0, 0, 1000, 750))

        # Even more stuff

        ventana.setCentralWidget(self.widget_central)
        QtCore.QMetaObject.connectSlotsByName(ventana)
        ventana.setWindowTitle("Dibujo técnico")
        ventana.show()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    ventana = QtWidgets.QMainWindow()
    ui = UiVentana()
    sys.exit(app.exec_())


Solution

  • You have to override the keyPressEvent() method and set the focusPolicy property to Qt::StrongFocus:

    class Render(QOpenGLWidget):
        # ...
        def keyPressEvent(self, event):
            if event.key() == QtCore.Qt.Key_Return:
                print("return")
            elif event.key() == QtCore.Qt.Key_Left:
                print("left")
            elif event.key() == QtCore.Qt.Key_0:
                print("0")
            elif event.key() == QtCore.Qt.Key_A:
                print("a")
            super().keyPressEvent(event)
    
    self.Visor = Render(self.widget_central)
    self.Visor.setFocusPolicy(QtCore.Qt.StrongFocus)
    

    Plus:

    class Render(QOpenGLWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
            self._z = -1.5
    
        def initializeGL(self):
            glClear(GL_COLOR_BUFFER_BIT)
            self.vertices_v = [[1, 1, 0], [1, -1, 0], [-1, -1, 0], [-1, 1, 0]]
            self.vertices_h = [[1, 0, -1], [1, 0, 1], [-1, 0, 1], [-1, 0, -1]]
            glEnable(GL_DEPTH_TEST)
    
        def paintGL(self):
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            glLoadIdentity()
            gluPerspective(60, 750 / 1000, 1, 30)
            glTranslatef(0, -0.5, self._z)
    
            glEnable(GL_BLEND)
            glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR)
            glBegin(GL_QUADS)
            glColor4fv((0, 1, 0, 0.6))
            for vertex in range(4):
                glVertex3fv(self.vertices_v[vertex])
            glColor4fv((1, 0, 0, 0.6))
            for vertex in range(4):
                glVertex3fv(self.vertices_h[vertex])
            glEnd()
    
        def keyPressEvent(self, event):
            if event.key() == QtCore.Qt.Key_Right:
                self._z -= 0.1
            elif event.key() == QtCore.Qt.Key_Left:
                self._z += 0.1
            self.update()
            super().keyPressEvent(event)