PyQtサンプル
情報収集をしつつPyQtの使用を開始。検索するときはむしろPyQt4とすべきかも。
とりあえずOpenGLの使い方を調べてみた。
pyqtのOpenGLサンプルhellogl.pywのコードを減らしながら解読。
QGLWidgetクラスがOpenGLを扱うクラスでこれを継承して、下記のメソッドをオーバーライドする仕組みだとわかった。
特にイベントとコールバックの結びつけなんかは要らなかった。
決まったメソッドをオーバーライドする方式らしい。
QGLWidgetのオーバーライドするメソッド
- paintGL()
- 描画時のコールバック
- resizeGL()
- ウィンドウリサイズ時のコールバック
- initializeGL()
- OpenGLの初期設定など
他にマウス関連のメソッドでmousePressEvent、mouseMoveEventなんかがあった。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import math from PyQt4 import QtCore, QtGui, QtOpenGL from OpenGL import GL, GLU class GLWidget(QtOpenGL.QGLWidget): def __init__(self, parent=None): QtOpenGL.QGLWidget.__init__(self, QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers), parent) self.xRot = 0 self.yRot = 0 self.zRot = 0 self.lastPos = QtCore.QPoint() self.trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) self.trolltechPurple = QtGui.QColor.fromCmykF(0.39, 0.39, 0.0, 0.0) def minimumSizeHint(self): return QtCore.QSize(50, 50) def sizeHint(self): return QtCore.QSize(150, 150) def setXRotation(self, angle): angle = self.normalizeAngle(angle) if angle != self.xRot: self.xRot = angle self.emit(QtCore.SIGNAL("xRotationChanged(int)"), angle) self.updateGL() def setYRotation(self, angle): angle = self.normalizeAngle(angle) if angle != self.yRot: self.yRot = angle self.emit(QtCore.SIGNAL("yRotationChanged(int)"), angle) self.updateGL() def setZRotation(self, angle): angle = self.normalizeAngle(angle) if angle != self.zRot: self.zRot = angle self.emit(QtCore.SIGNAL("zRotationChanged(int)"), angle) self.updateGL() def initializeGL(self): self.qglClearColor(self.trolltechPurple.dark()) GL.glClearDepth(1.0) self.object = self.makeObject() #GL.glShadeModel(GL.GL_FLAT) GL.glShadeModel(GL.GL_SMOOTH) GL.glDepthFunc(GL.GL_LESS) GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_CULL_FACE) def paintGL(self): GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) GL.glLoadIdentity() GL.glTranslated(0.0, 0.0, -10.0) GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) GL.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) GL.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) GL.glEnable(GL.GL_LIGHTING) GL.glEnable(GL.GL_LIGHT0) GL.glCallList(self.object) def resizeGL(self, width, height): side = min(width, height) GL.glViewport((width - side) / 2, (height - side) / 2, side, side) GL.glMatrixMode(GL.GL_PROJECTION) GL.glLoadIdentity() GL.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0) GL.glMatrixMode(GL.GL_MODELVIEW) def mousePressEvent(self, event): self.lastPos = QtCore.QPoint(event.pos()) def mouseMoveEvent(self, event): dx = event.x() - self.lastPos.x() dy = event.y() - self.lastPos.y() if event.buttons() & QtCore.Qt.LeftButton: self.setXRotation(self.xRot + 8 * dy) self.setYRotation(self.yRot + 8 * dx) elif event.buttons() & QtCore.Qt.RightButton: self.setXRotation(self.xRot + 8 * dy) self.setZRotation(self.zRot + 8 * dx) self.lastPos = QtCore.QPoint(event.pos()) def makeObject(self): vertices=[ (-0.1, -0.1, -0.1), (0.1, -0.1, -0.1), (0.1, -0.1, 0.1), (-0.1, -0.1, 0.1), (-0.1, 0.1, -0.1), (0.1, 0.1, -0.1), (0.1, 0.1, 0.1), (-0.1, 0.1, 0.1), ] faces=[ (0, 1, 2, 3), (7, 6, 5, 4), (1, 0, 4, 5), (2, 1, 5, 6), (3, 2, 6, 7), (0, 3, 7, 4) ] normals=[(0, -1, 0), (0, 1, 0), (0, 0, 1), (1, 0, 0), (0, 0, -1), (-1, 0, 0)] genList = GL.glGenLists(1) GL.glNewList(genList, GL.GL_COMPILE) GL.glEnable(GL.GL_NORMALIZE) GL.glBegin(GL.GL_QUADS) self.qglColor(self.trolltechGreen) for i in range(len(faces)): GL.glNormal3dv(normals[i]) GL.glVertex(vertices[faces[i][0]]) GL.glVertex(vertices[faces[i][1]]) GL.glVertex(vertices[faces[i][2]]) GL.glVertex(vertices[faces[i][3]]) GL.glEnd() GL.glEndList() return genList def normalizeAngle(self, angle): while angle < 0: angle += 360 * 16 while angle > 360 * 16: angle -= 360 * 16 return angle class Window(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.glWidget = GLWidget() mainLayout = QtGui.QHBoxLayout() mainLayout.addWidget(self.glWidget) self.setLayout(mainLayout) self.setWindowTitle(self.tr("Hello GL")) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())