PyQt 1 (ボタン、スライダ、OpenGL)

PyQt

PyQtとは、GUIツールキットQtのPythonバインドです。
Windows, MacOS X, Linux など多くのOS上で動作します。
ここで使用しているモジュールは以下の通りです。

PyQt4.QtCore
GUIを含まない処理を行うためのモジュールです。
シグナルやスロットなどを含みます。
PyQt4.QtGui
GUIを作成するためのモジュールです。
PyQt4.QtOpenGL
OpenGLのためのモジュールです。

何もないウインドウ

  1. 以下のスクリプトを、pyqt1.py というファイル名で保存します。
    #!env python
    import sys
    from PyQt4 import QtGui
    
    app = QtGui.QApplication(sys.argv)
    
    widget = QtGui.QWidget()
    widget.resize(300, 300)
    widget.setWindowTitle('PyQt 1')
    widget.show()
    
    sys.exit(app.exec_())
    
  2. 以下のように実行します。
    # python pyqt1.py
    [何もないウインドウ]

スクリプト解説

from PyQt4 import QtGui
PyQt4モジュールからQtGuiモジュールをインポートします。
app = QtGui.QApplication(sys.argv)
applicationオブジェクトを作成します。
applicationオプジェクとはPyQt4アプリケーションでは必ず作成しなくてはなりません。 
widget = QtGui.QWidget()
他のウィジェットのベースになるウィジェットを作成します。
widget.resize(300, 300)
ウィジェットの大きさを300 X 300にします。
widget.setWindowTitle('PyQt 1')
ウインドウのタイトルを設定します。
widget.show()
ウィジェットを表示します。
sys.exit(app.exec_())
applicationオブジェクトのexec_メソッドにより、メインループを実行します。
スクリプトの終了は、sys.exit()メソッドによって行います。

ボタン

  1. 以下のスクリプトを、pyqt2.py というファイル名で保存します。
    #!env python
    import sys
    from PyQt4 import QtGui, QtCore
    
    
    class QuitButton(QtGui.QWidget):
        def __init__(self, parent=None):
            QtGui.QWidget.__init__(self, parent)
    
            self.setGeometry(50, 50, 300, 300)
            self.setWindowTitle('Close button')
    
            cb = QtGui.QPushButton('Close', self)
            cb.setGeometry(10, 10, 60, 35)
    
            cb.clicked.connect(QtGui.qApp.quit)
    
    
    app = QtGui.QApplication(sys.argv)
    b = QuitButton()
    b.show()
    sys.exit(app.exec_())
    
  2. 以下のように実行します。
    # python pyqt2.py
    [ボタンのついたウインドウ]

スクリプト解説

from PyQt4 import QtGui, QtCore
QtGui, QtCoreモジュールをインポートします。
class QuitButton(QtGui.QWidget):
ボタンウィジェットを作成して、必要な設定をするクラスの定義です。
ウィジェットの定義なので、QtGui.QWidgetクラスを継承します。
def __init__(self, parent=None):
親ウィジェットをparentとして、初期化メソッドを定義します。
親ウィジェットがない場合は、parentはNoneになります。
QtGui.QWidget.__init__(self, parent)
QtGui.QWidgetクラスの初期かメソッドを実行します。
self.setGeometry(50, 50, 300, 300)
このウィジェットは(50, 50)の位置から、300 X 300 の大きさで表示されます。
self.setWindowTitle('Close button')
ウインドウのタイトルを設定します。
cb = QtGui.QPushButton('Close', self)
ボタンウィジェットを作成します。
cb.setGeometry(10, 10, 60, 35)
ボタンウィジェットは、ウインドウ内の(10, 10)の位置から、60 X 35 の大きさで表示されます。
cb.clicked.connect(QtGui.qApp.quit)
ボタンがマウスによってクリックされたら、実行する関数を定義します。
QtCore.SIGNAL('clicked()') がマウスがクリックしたというシグナルで、 quit() がそのときに実行される関数になります。
b = QuitButton()
QuitButtonクラスのインスタンスを作成することによって、ボタンウィジェットを作ります。
b.show()
ボタンを表示します。

スライダ

  1. 以下のスクリプトを、pyqt3.py というファイル名で保存します。
    #!env python
    import sys
    from PyQt4 import QtGui
    from PyQt4 import QtCore
    
    
    class sliderWindow(QtGui.QWidget):
        def __init__(self):
            super(sliderWindow, self).__init__()
                                  
            slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
            slider.setFocusPolicy(QtCore.Qt.NoFocus)
            slider.setGeometry(30, 40, 100, 30)
            slider.valueChanged.connect(self.changeValue)
    
            self.label = QtGui.QLabel(self)
            self.label.setText('0')
            self.label.setGeometry(160, 40, 80, 30)
              
            self.setWindowTitle('Slider')
            self.setGeometry(50, 50, 300, 300)
              
        def changeValue(self, value):
            self.label.setText(str(value))
    
    
    app = QtGui.QApplication(sys.argv)
    s = sliderWindow()
    s.show()
    sys.exit(app.exec_())
    
  2. 以下のように実行します。
    # python pyqt3.py
    [スライダのついたウインドウ]

スクリプト解説

from PyQt4 import QtGui
QtGuiモジュールをインポートします。
from PyQt4 import QtCore
QtCoreモジュールをインポートします。
class sliderWindow(QtGui.QWidget):
スライダウィジェットを作成して、必要な設定をするクラスの定義です。
ウィジェットの定義なので、QtGui.QWidgetクラスを継承します。
def __init__(self):
初期化メソッドを定義します。
super(sliderWindow, self).__init__()
親クラスの初期化メソッドを実行します。
ここでは、親クラスはQtGui.QWidgetクラスです。
slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
スライダウィジェットを作成します。
向きは水平方向(QtCore.Qt.Horizontal)で、親ウィジェットはこのクラス(self)になります。
slider.setFocusPolicy(QtCore.Qt.NoFocus)
このスライダはフォーカスを与えない設定にします。
slider.setGeometry(30, 40, 100, 30)
このスライダは、ウインドウ内で(30, 40)の位置から 100 X 30 の大きさで表示します。
slider.valueChanged.connect(self.changeValue)
このスライダの値が変化(valueChanged(int))したら、このクラスのchangeValue()メソッドを実行します。
self.label = QtGui.QLabel(self)
ラベルウィジェットを作成します。
self.label.setText('0')
ラベルウィジェットのテキストを'0'に設定します。
self.label.setGeometry(160, 40, 80, 30)
ラベルウィジェットを(160, 40)の位置から 80 X 30 の大きさで表示します。
self.setWindowTitle('Slider')
ウインドウのタイトルを設定します。
self.setGeometry(50, 50, 300, 300)
このウインドウを(50, 50)の位置から 300 X 300 の大きさで表示します。
def changeValue(self, value):
スライダの値が変化したときに実行されるメソッドです。
valueがそのときのスライダの値(int)です。
self.label.setText(str(value))
ラベルの表示をvalueを文字列に変換したものに変えます。

OpenGL ウィジェット

PyQtでOpenGLの描画をするには、QGLWidgetを継承したクラスを作成し、 その中で設定•描画します。

initializeGL(self)
OpenGLの初期化メソッドです。
paintGL()とresizeGL()は、このメソッド実行の後に実行されます。
glutInit(), glutInitWindowSize(), glutCreateWindow() などを実行する必要はありません。
paintGL(self)
OpenGL描画メソッドです。
glutDisplayFunc()は使用しません。
resizeGL(self, w, h)
ウインドウがリサイズされたときに実行するメソッドです。
glutReshapeFunc()は使用しません。
updateGL()
再描画をさせるメソッドです。
glutPostRedisplay()は使用しません。
mousePressEvent(self, event)
マウスボタンが押された時に実行されるメソッド
p = event.pos() と実行すると、p.x と p.y にマウスの位置が入っています。
どのボタンが押されたかは、以下のスクリプトで判断できます。
b = event.button()
if b == Qt.LeftButton:
	# 右ボタン
elif b == Qt.MiddleButton:
	# 中ボタン
elif b == Qt.RightButton:
	# 左ボタン
mouseReleaseEvent(self, evnet)
マウスボタンが離された時に実行されるメソッド
mouseMoveEvent(self, evnet)
マウスボタンがドラッグされた時に実行されるメソッド
keyPressEvent()
キーが押された時に実行されるメソッド
evnet.key()で押されたキーのコードを得ることができます。
keyReleaseEvent()
キーが離された時に実行されるメソッド
evnet.key()で離されたキーのコードを得ることができます。

OpenGL ウィジェットの例

  1. 以下のスクリプトを、pyqt4.py というファイル名で保存します。
    #!env python
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    from PyQt4 import QtGui
    from PyQt4.QtOpenGL import *
    
    
    class QTGLWidget1(QGLWidget):
        vertex = [
            [ 0.0, 0.0, 0.0 ],
            [ 1.0, 0.0, 0.0 ],
            [ 1.0, 1.0, 0.0 ],
            [ 0.0, 1.0, 0.0 ],
            [ 0.0, 0.0, 1.0 ],
            [ 1.0, 0.0, 1.0 ],
            [ 1.0, 1.0, 1.0 ],
            [ 0.0, 1.0, 1.0 ]]
    
        edge = [
            [ 0, 1 ],
            [ 1, 2 ],
            [ 2, 3 ],
            [ 3, 0 ],
            [ 4, 5 ],
            [ 5, 6 ],
            [ 6, 7 ],
            [ 7, 4 ],
            [ 0, 4 ],
            [ 1, 5 ],
            [ 2, 6 ],
            [ 3, 7 ]]
    
        def __init__(self, parent):
            QGLWidget.__init__(self, parent)
            self.setMinimumSize(300, 300)
    
        def paintGL(self):
            glClearColor(0.0, 0.0, 1.0, 0.0)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            
            glLoadIdentity()
            gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    
            glBegin(GL_LINES)
            for i in range(0, 12):
                glVertex(self.vertex[self.edge[i][0]])
                glVertex(self.vertex[self.edge[i][1]])
            glEnd()
    
            glFlush()
    
        def resizeGL(self, w, h):
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            gluPerspective(30.0, w/h, 1.0, 100.0)
            glMatrixMode(GL_MODELVIEW)
        
        def initializeGL(self):
            glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    
            glClearColor(0.0, 0.0, 0.0, 1.0)
            glClearDepth(1.0)
    
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            gluPerspective(40.0, 1.0, 1.0, 30.0)
    
    
            
    class QTGLSample(QtGui.QMainWindow):
        def __init__(self):
            QtGui.QMainWindow.__init__(self)
            widget = QTGLWidget1(self)    
            self.setCentralWidget(widget)
    
    
    app = QtGui.QApplication(sys.argv)
    window = QTGLSample()
    window.setWindowTitle('PyQt OpenGL 1')
    window.show()
    sys.exit(app.exec_())
    
  2. 以下のように実行します。
    # python pyqt4.py
    [OpenGL表示ウインドウ]

スクリプト解説

from PyQt4.QtOpenGL import *
QtOpenGLモジュールをインポートします。
class QTGLWidget1(QGLWidget):
PyQt4.QtOpenGL.QGLWidgetクラスを継承して、OpenGLのウィジェットクラスを定義します。
def __init__(self, parent):
親ウィジェットをparentにして、初期化メソッドを定義します。
QGLWidget.__init__(self, parent)
親クラス(QGLWidget)の初期化メソッドを実行します。
self.setMinimumSize(300, 300)
ウインドウの最小サイズを 300 X 300 にします。
def paintGL(self):
OpenGLによって描画するメソッドです。
def resizeGL(self, w, h):
ウインドウがリサイズされたときに実行されるメソッドです。
def initializeGL(self):
OpenGLを初期化するメソッドです。
glutInit()は実行する必要がありません。
class QTGLSample(QtGui.QMainWindow):
QtGui.QMainWindowを継承して、ウインドウのクラスを定義します。
QtGui.QMainWindow.__init__(self)
親クラス(QtGui.QMainWindow)の初期化メソッドを実行します。
widget = QTGLWidget1(self)
OpenGLのウィジェットを作成します。
self.setCentralWidget(widget)
ウィジェットをウインドウの中心に表示します。

レイアウト

レイアウトの作成•設定をするためのメソッドです。

QtGui.QHBoxLayout()
ウィジェット•レイアウトを水平に並べるレイアウトのインスタンスを作成
QtGui.QVBoxLayout()
ウィジェット•レイアウトを垂直に並べるレイアウトのインスタンスを作成
addWidget(widget)
レイアウトにウィジェットを追加するメソッド
addLayout(layout)
レイアウトにレイアウトを追加するメソッド
setLayout(layout)
ウィジェットのレイアウトを設定するメソッド

レイアウトの例

  1. 以下のスクリプトを、pyqt5.py というファイル名で保存します。
    #!env python
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    from PyQt4 import QtGui
    from PyQt4 import QtCore
    from PyQt4.QtOpenGL import *
    
    
    class QTGLWidget2(QGLWidget):
        vertex = [
            [ 0.0, 0.0, 0.0 ],
            [ 1.0, 0.0, 0.0 ],
            [ 1.0, 1.0, 0.0 ],
            [ 0.0, 1.0, 0.0 ],
            [ 0.0, 0.0, 1.0 ],
            [ 1.0, 0.0, 1.0 ],
            [ 1.0, 1.0, 1.0 ],
            [ 0.0, 1.0, 1.0 ]]
    
        edge = [
            [ 0, 1 ],
            [ 1, 2 ],
            [ 2, 3 ],
            [ 3, 0 ],
            [ 4, 5 ],
            [ 5, 6 ],
            [ 6, 7 ],
            [ 7, 4 ],
            [ 0, 4 ],
            [ 1, 5 ],
            [ 2, 6 ],
            [ 3, 7 ]]
    
        def __init__(self, parent):
            QGLWidget.__init__(self, parent)
            self.setMinimumSize(300, 300)
            self.br = 0.0
            self.bg = 0.0
            self.bb = 1.0
    
        def paintGL(self):
            glClearColor(self.br, self.bg, self.bb, 0.0)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            
            glLoadIdentity()
            gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    
            glBegin(GL_LINES)
            for i in range(0, 12):
                glVertex(self.vertex[self.edge[i][0]])
                glVertex(self.vertex[self.edge[i][1]])
            glEnd()
    
            glFlush()
    
        def resizeGL(self, w, h):
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            gluPerspective(30.0, w/h, 1.0, 100.0)
            glMatrixMode(GL_MODELVIEW)
        
        def initializeGL(self):
            glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    
            glClearColor(self.br, self.bg, self.bb, 1.0)
            glClearDepth(1.0)
    
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            gluPerspective(40.0, 1.0, 1.0, 30.0)
    
        def changeBackColor(self):
            c = self.br
            self.br = self.bg
            self.bg = self.bb
            self.bb = c
            self.updateGL()
    
    
    class QTWidget(QtGui.QWidget):
        def __init__(self):
            QtGui.QWidget.__init__(self)
    
            self.gl = QTGLWidget2(self)
            bb = QtGui.QPushButton('Back Color', self)
            bb.clicked.connect(self.gl.changeBackColor)
            cb = QtGui.QPushButton('Close', self)
            cb.clicked.connect(QtGui.qApp.quit)
    
            hbox = QtGui.QHBoxLayout()
            hbox.addWidget(bb)
            hbox.addWidget(cb)
    
            vbox = QtGui.QVBoxLayout()
            vbox.addWidget(self.gl)
            vbox.addLayout(hbox)
    
            self.setLayout(vbox)
    
            self.resize(300, 350)
    
    
    app = QtGui.QApplication(sys.argv)
    w = QTWidget()
    w.setWindowTitle('PyQt OpenGL 2')
    w.show()
    sys.exit(app.exec_())
    
  2. 以下のように実行します。
    # python pyqt5.py
  3. Back Color ボタンを押すと、バックの色が変化します。
    [レイアウト] [レイアウト] [レイアウト]

スクリプト解説

self.br = 0.0
self.bg = 0.0
self.bb = 1.0
GLウィジェットのバック色を設定する変数です。
def changeBackColor(self):
バックの色を変更するメソッドです。
c = self.br
self.br = self.bg
self.bg = self.bb
self.bb = c
色を入れ換える計算です。
self.updateGL()
再描画を行います。
glutPostRedisplay()の代わりに使用します。
class QTWidget(QtGui.QWidget):
ウインドウに表示するウィジェットの定義です。
self.gl = QTGLWidget2(self)
OpenGLウィジェットのインスタンスを作成します。
bb = QtGui.QPushButton('Back Color', self)
'Back Color'というラベルのついたボタンを作成します。
bb.clicked.connect(self.gl.changeBackColor)
ボタンをクリックしたときに、self.gl.changeBackColor()メソッドを実行させる設定です。
cb = QtGui.QPushButton('Close', self)
ウインドウを閉じるボタンを作成します。
cb.clicked.connect(QtGui.qApp.quit)
'Close'ボタンをクリックしたときに、ウインドウを閉じる設定をします。
hbox = QtGui.QHBoxLayout()
ウィジェットを横に並べるレイアウトを作成します。
hbox.addWidget(bb)
hbox.addWidget(cb)
横に並べるレイアウトに、2つのボタンを追加します。
vbox = QtGui.QVBoxLayout()
ウィジェットを縦に並べるレイアウトを作成します。
vbox.addWidget(self.gl)
vbox.addLayout(hbox)
縦に並べるレイアウトに、OpenGLウィジェットと、横に並べるレイアウトを追加します。
self.setLayout(vbox)
このウィジェットのレイアウトに縦に並べるレイアウトを指定します。

参考


Prev | Next
index | home
abetmhr@gmail.com