PyQt5 + PyOpenGL Example
It took a little bit for me to find working example code for PyOpenGL+PyQt5. The following exposes a GLUT-like interface where you can provide callback functions for basic window, mouse and keyboard events.
# simple_viewer.py
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtOpenGL
class SimpleViewer(QtOpenGL.QGLWidget):
initialize_cb = QtCore.pyqtSignal()
resize_cb = QtCore.pyqtSignal(int,int)
idle_cb = QtCore.pyqtSignal()
render_cb = QtCore.pyqtSignal()
mouse_move_cb = QtCore.pyqtSignal( QtGui.QMouseEvent )
mouse_press_cb = QtCore.pyqtSignal( QtGui.QMouseEvent )
mouse_release_cb = QtCore.pyqtSignal( QtGui.QMouseEvent )
mouse_wheel_cb = QtCore.pyqtSignal( QtGui.QWheelEvent )
key_press_cb = QtCore.pyqtSignal( QtGui.QKeyEvent )
key_release_cb = QtCore.pyqtSignal( QtGui.QKeyEvent )
def __init__(self, parent=None):
self.parent = parent
QtOpenGL.QGLWidget.__init__(self, parent)
self.setMouseTracking(True)
def mouseMoveEvent( self, evt ):
self.mouse_move_cb.emit( evt )
def mousePressEvent( self, evt ):
self.mouse_press_cb.emit( evt )
def mouseReleaseEvent( self, evt ):
self.mouse_release_cb.emit( evt )
def keyPressEvent( self, evt ):
self.key_press_cb.emit(evt)
def keyReleaseEvent( self, evt ):
self.key_release_cb.emit(evt)
def initializeGL(self):
self.initialize_cb.emit()
def resizeGL(self, width, height):
if height == 0: height = 1
self.resize_cb.emit(width,height)
def paintGL(self):
self.render_cb.emit()
And here is a basic example using it:
"""About the simplest PyQt OpenGL example with decent interaction"""
import sys
from OpenGL.GL import *
from OpenGL.GLU import *
from simple_viewer import SimpleViewer
width = 800
height = 600
aspect = width/height
def resize( w, h ):
width = w
height = h
aspect = w/h
glViewport( 0, 0, width, height )
def initialize():
glEnable(GL_DEPTH_TEST)
glClearColor( 0.7, 0.7, 1.0, 0.0 )
def render():
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glMatrixMode( GL_PROJECTION )
glLoadIdentity()
gluPerspective( 45.0, aspect, 0.1, 10.0 )
glMatrixMode( GL_MODELVIEW )
glLoadIdentity()
gluLookAt( 0.0, 2.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 )
glPointSize(5.0)
glLineWidth(5.0)
glBegin(GL_LINES)
glColor3f( 1.0, 0.0, 0.0 )
glVertex3f( 1.0, 0.0, 0.0 )
glVertex3f( 0.0, 0.0, 0.0 )
glColor3f( 0.0, 1.0, 0.0 )
glVertex3f( 0.0, 1.0, 0.0 )
glVertex3f( 0.0, 0.0, 0.0 )
glColor3f( 0.0, 0.0, 1.0 )
glVertex3f( 0.0, 0.0, 1.0 )
glVertex3f( 0.0, 0.0, 0.0 )
glEnd()
def mouse_move( evt ):
print('Mouse move {}: [{},{}]'.format(evt.button(),evt.x(),evt.y()) )
def mouse_press( evt ):
print('Mouse press {}: [{},{}]'.format(evt.button(),evt.x(),evt.y()) )
def mouse_release( evt ):
print('Mouse release {}: [{},{}]'.format(evt.button(),evt.x(),evt.y()) )
def key_press( evt ):
print('Key press {}'.format(evt.key()) )
def key_release( evt ):
print('Key release {}'.format(evt.key()) )
# create the QApplication
app = SimpleViewer.application()
# set up the display
viewer = SimpleViewer()
viewer.resize_cb.connect( resize )
viewer.initialize_cb.connect( initialize )
viewer.render_cb.connect( render )
# keyboard & mouse interactions
viewer.key_press_cb.connect( key_press )
viewer.key_release_cb.connect( key_release )
viewer.mouse_press_cb.connect( mouse_press )
viewer.mouse_release_cb.connect( mouse_release )
viewer.mouse_move_cb.connect( mouse_move )
# resize the window
viewer.resize( width, height )
viewer.show()
# main loop
try:
sys.exit(app.exec_())
except SystemExit:
pass