[PyQt] Using Python's "print" or sys.stdout.write( "str" ) inside of PyQt4.

Peter Lindener lindener.peter at gmail.com
Thu Sep 25 21:40:11 BST 2008


Skipped content of type multipart/alternative-------------- next part --------------
#!/usr/bin/env python

print "--- Hello_PyQtOpenGL_PL.py ------------------------------------"
print

"""PyQt4 port of the opengl/hellogl example from Qt v4.x"""

"""
This code is a minor modification by PL. of the PyQt4 example code typicaly found on the path:
C:\Python25\Lib\site-packages\PyQt4\examples\opengl\hellogl.py

It has been modifyed to "print" out (or log to a file) the values of the OpenGL trasnformation Matrixs.
This value logging is envoked inside the Qt4 "GLWidget.paintGL()" call back method.

Bug --> Apparently using print statments at this point in the demo program's flow does not work also so well
when one is working inside of Python's default develpment enviroment IDLE (Python 2.5,2, with IDLE version 1.2.2 under Win_XP-sp2).
While these print statments still seems to work with the Python interpreter when involked stand alone.  I also note that "sys.stdout.write()" also fails, and Python's error
reporting fails to display within IDLE when there are failyers in this same part of the code.

The above IDLE/PyQt/OpenGL print bug is clearly is an isssue if we want to think of one of Python's vertues as being that of highly
interactive visual code development.

Other minor changes to the code:
    Opening and Closing program name print statments,
    Import from numpy
    Added raw_input() wait for [Enter] and then
    A call to window.close() to properly clean up PyQt at end of program 

"""

# LogFileName = None             # "print" Does not work inside of Python's IDLE
LogFileName = "stdout"         # a clue.. ..sys.stdout.write() does not work either

# LogFileName = "Log.txt"      # Works inside with IDLE


print "LogFileName: %s" % ( LogFileName )

#-------    

def Log_String( String, InitFile=False ) :
    if(   LogFileName == None )     :  print String
    
    elif( LogFileName == "stdout" ) :  sys.stdout.write( String )

    else :    
        LogFile = open( "Log.txt", 'w' if(InitFile) else 'a' )
        LogFile.write( String + '\n' )
        LogFile.close()


#---

import sys
import math
from   numpy import int32

#---

from   PyQt4 import QtCore, QtGui, QtOpenGL

try:
    from OpenGL import GL
    
except ImportError:
    app = QtGui.QApplication(sys.argv)
    QtGui.QMessageBox.critical(None, "OpenGL hellogl",
                            "PyOpenGL must be installed to run this example.",
                            QtGui.QMessageBox.Ok | QtGui.QMessageBox.Default,
                            QtGui.QMessageBox.NoButton)
    sys.exit(1)


#----------------------------------

def Get_OpenGL_ModelViewMat() :    
    Mat4x4 = GL.glGetFloatv( GL.GL_MODELVIEW_MATRIX )
    return( Mat4x4.T )

def Get_OpenGL_ProjectionMat() :    
    Mat4x4 = GL.glGetFloatv( GL.GL_PROJECTION_MATRIX )
    return( Mat4x4.T )

#-------

def Set_OpenGL_ModelViewMat( Mat4x4 ) :    
    GL.glMatrixMode( GL_MODELVIEW )          # Set stupped Open_GL Matrix access state
    GL.glLoadMatrix( Mat4x4.T )

def Set_OpenGL_ProjectionMat( Mat4x4 ) :    
    GL.glMatrixMode( GL_PROJECTION )         # Set stupped Open_GL Matrix access state
    GL.glLoadMatrix( Mat4x4.T )

#----

def Log_OpenGL_Matrixs() :
    ModVMatStr = "GL_ModelViewMat:\n%s\n"  % ( int32(Get_OpenGL_ModelViewMat() *100) ) 
    ProjMatStr = "GL_ProjectionMat:\n%s\n" % ( int32(Get_OpenGL_ProjectionMat()*100) ) 
    Log_String( ModVMatStr + ProjMatStr )

    return

    
#-----------------------------------------------------------------------------

class Window(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.glWidget = GLWidget()

        self.xSlider = self.createSlider(QtCore.SIGNAL("xRotationChanged(int)"),
                                         self.glWidget.setXRotation)
        self.ySlider = self.createSlider(QtCore.SIGNAL("yRotationChanged(int)"),
                                         self.glWidget.setYRotation)
        self.zSlider = self.createSlider(QtCore.SIGNAL("zRotationChanged(int)"),
                                         self.glWidget.setZRotation)

        mainLayout = QtGui.QHBoxLayout()
        mainLayout.addWidget(self.glWidget)
        mainLayout.addWidget(self.xSlider)
        mainLayout.addWidget(self.ySlider)
        mainLayout.addWidget(self.zSlider)
        self.setLayout(mainLayout)

        self.xSlider.setValue(15 * 16)
        self.ySlider.setValue(345 * 16)
        self.zSlider.setValue(0 * 16)

        self.setWindowTitle(self.tr("Hello_PyQtOpenGL"))
        

    def createSlider(self, changedSignal, setterSlot):
        slider = QtGui.QSlider(QtCore.Qt.Vertical)

        slider.setRange(0, 360 * 16)
        slider.setSingleStep(16)
        slider.setPageStep(15 * 16)
        slider.setTickInterval(15 * 16)
        slider.setTickPosition(QtGui.QSlider.TicksRight)

        self.glWidget.connect(slider, QtCore.SIGNAL("valueChanged(int)"), setterSlot)
        self.connect(self.glWidget, changedSignal, slider, QtCore.SLOT("setValue(int)"))

        return slider
    
#------

class GLWidget(QtOpenGL.QGLWidget):
    def __init__(self, parent=None):
        QtOpenGL.QGLWidget.__init__(self, parent)

        self.object = 0
        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 xRotation(self):
        return self.xRot

    def yRotation(self):
        return self.yRot

    def zRotation(self):
        return self.zRot

    def minimumSizeHint(self):
        return QtCore.QSize(50, 50)

    def sizeHint(self):
#       return QtCore.QSize(400, 400)
        return QtCore.QSize(800, 800)      # Larger inital window, PL.

    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())
        self.object = self.makeObject()
        GL.glShadeModel(GL.GL_FLAT)
        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)
#---------       
        Log_OpenGL_Matrixs()        # For debuging Python side OpenGL matrix creation, PL.
#---------
        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):
        genList = GL.glGenLists(1)
        GL.glNewList(genList, GL.GL_COMPILE)

        GL.glBegin(GL.GL_QUADS)

        x1 = +0.06
        y1 = -0.14
        x2 = +0.14
        y2 = -0.06
        x3 = +0.08
        y3 = +0.00
        x4 = +0.30
        y4 = +0.22

        self.quad(x1, y1, x2, y2, y2, x2, y1, x1)
        self.quad(x3, y3, x4, y4, y4, x4, y3, x3)

        self.extrude(x1, y1, x2, y2)
        self.extrude(x2, y2, y2, x2)
        self.extrude(y2, x2, y1, x1)
        self.extrude(y1, x1, x1, y1)
        self.extrude(x3, y3, x4, y4)
        self.extrude(x4, y4, y4, x4)
        self.extrude(y4, x4, y3, x3)

        Pi = 3.14159265358979323846
        NumSectors = 200

        for i in range(NumSectors):
            angle1 = (i * 2 * Pi) / NumSectors
            x5 = 0.30 * math.sin(angle1)
            y5 = 0.30 * math.cos(angle1)
            x6 = 0.20 * math.sin(angle1)
            y6 = 0.20 * math.cos(angle1)

            angle2 = ((i + 1) * 2 * Pi) / NumSectors
            x7 = 0.20 * math.sin(angle2)
            y7 = 0.20 * math.cos(angle2)
            x8 = 0.30 * math.sin(angle2)
            y8 = 0.30 * math.cos(angle2)

            self.quad(x5, y5, x6, y6, x7, y7, x8, y8)

            self.extrude(x6, y6, x7, y7)
            self.extrude(x8, y8, x5, y5)

        GL.glEnd()
        GL.glEndList()

        return genList

    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
        self.qglColor(self.trolltechGreen)

        GL.glVertex3d(x1, y1, -0.05)
        GL.glVertex3d(x2, y2, -0.05)
        GL.glVertex3d(x3, y3, -0.05)
        GL.glVertex3d(x4, y4, -0.05)

        GL.glVertex3d(x4, y4, +0.05)
        GL.glVertex3d(x3, y3, +0.05)
        GL.glVertex3d(x2, y2, +0.05)
        GL.glVertex3d(x1, y1, +0.05)

    def extrude(self, x1, y1, x2, y2):
        self.qglColor(self.trolltechGreen.dark(250 + int(100 * x1)))

        GL.glVertex3d(x1, y1, +0.05)
        GL.glVertex3d(x2, y2, +0.05)
        GL.glVertex3d(x2, y2, -0.05)
        GL.glVertex3d(x1, y1, -0.05)

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle

    
#--------------------------------------    

if __name__ == '__main__':

    Log_String( "Hello_PyQtOpenGL.py -- LogFile ---------\n", InitFile=True )

#----
    
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()

    raw_input( "Type [Enter] to exit program" )

    window.close()      # Add by PL, missing in original PyQt example program

#----
    
    Log_String( "Hello_PyQtOpenGL.py -- End of LogFile --\n" )
   
#   sys.exit(app.exec_())   

print 
print "--- Hello_PyQtOpenGL_PL.py --- Done ------------------------------"
    


More information about the PyQt mailing list