View  Edit  Attributes  History  Attach  Print  Search

PYQTLAB

PyQt Lab' : 3D avec OpenGL :

Par X. HINAULT - Juin 2013

Ce que l'on va faire ici

  • Je vous propose ici de réaliser une interface simple affichant le repère 3D de base et permettant de le visualiser en appliquant rotation et translation.

Pré-requis

  • python 2.7
  • pyqt4.x
  • python-opengl

Le fichier d'interface *.ui


<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>540</width>
    <height>365</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>pyqt + openGL : translation/rotation du repère 3D de base</string>
  </property>
  <widget class="QWidget" name="horizontalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>320</width>
     <height>240</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout"/>
  </widget>
  <widget class="QLabel" name="labelTranslation">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>10</y>
     <width>81</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Translation :</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEditTx">
   <property name="geometry">
    <rect>
     <x>370</x>
     <y>30</y>
     <width>45</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>10</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonTxMoins">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>30</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>-X</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonTxPlus">
   <property name="geometry">
    <rect>
     <x>420</x>
     <y>30</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>+X</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonTyMoins">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>60</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>-Y</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonTyPlus">
   <property name="geometry">
    <rect>
     <x>420</x>
     <y>60</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>+Y</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEditTy">
   <property name="geometry">
    <rect>
     <x>370</x>
     <y>60</y>
     <width>45</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>10</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonTzMoins">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>90</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>-Z</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonTzPlus">
   <property name="geometry">
    <rect>
     <x>420</x>
     <y>90</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>+Z</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEditTz">
   <property name="geometry">
    <rect>
     <x>370</x>
     <y>90</y>
     <width>45</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>10</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRxMoins">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>140</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>-X</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEditRy">
   <property name="geometry">
    <rect>
     <x>370</x>
     <y>170</y>
     <width>45</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>10</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRxPlus">
   <property name="geometry">
    <rect>
     <x>420</x>
     <y>140</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>+X</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRzMoins">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>200</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>-Z</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRzPlus">
   <property name="geometry">
    <rect>
     <x>420</x>
     <y>200</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>+Z</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEditRz">
   <property name="geometry">
    <rect>
     <x>370</x>
     <y>200</y>
     <width>45</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>10</string>
   </property>
  </widget>
  <widget class="QLabel" name="labelRotation">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>120</y>
     <width>81</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Rotation</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRyMoins">
   <property name="geometry">
    <rect>
     <x>340</x>
     <y>170</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>-Y</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="lineEditRx">
   <property name="geometry">
    <rect>
     <x>370</x>
     <y>140</y>
     <width>45</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>10</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRyPlus">
   <property name="geometry">
    <rect>
     <x>420</x>
     <y>170</y>
     <width>23</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>+Y</string>
   </property>
  </widget>
  <widget class="QLCDNumber" name="lcdNumberRx">
   <property name="geometry">
    <rect>
     <x>450</x>
     <y>140</y>
     <width>64</width>
     <height>20</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 255, 127);
color: rgb(0, 85, 0);</string>
   </property>
   <property name="segmentStyle">
    <enum>QLCDNumber::Flat</enum>
   </property>
  </widget>
  <widget class="QLabel" name="labelRx">
   <property name="geometry">
    <rect>
     <x>520</x>
     <y>150</y>
     <width>20</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Rx</string>
   </property>
  </widget>
  <widget class="QLabel" name="labelRy">
   <property name="geometry">
    <rect>
     <x>520</x>
     <y>180</y>
     <width>20</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Ry</string>
   </property>
  </widget>
  <widget class="QLCDNumber" name="lcdNumberRy">
   <property name="geometry">
    <rect>
     <x>450</x>
     <y>170</y>
     <width>64</width>
     <height>20</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 255, 127);
color: rgb(0, 85, 0);</string>
   </property>
   <property name="segmentStyle">
    <enum>QLCDNumber::Flat</enum>
   </property>
  </widget>
  <widget class="QLabel" name="labelRz">
   <property name="geometry">
    <rect>
     <x>520</x>
     <y>210</y>
     <width>20</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Rz</string>
   </property>
  </widget>
  <widget class="QLCDNumber" name="lcdNumberRz">
   <property name="geometry">
    <rect>
     <x>450</x>
     <y>200</y>
     <width>64</width>
     <height>20</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 255, 127);
color: rgb(0, 85, 0);</string>
   </property>
   <property name="segmentStyle">
    <enum>QLCDNumber::Flat</enum>
   </property>
  </widget>
  <widget class="QLCDNumber" name="lcdNumberTz">
   <property name="geometry">
    <rect>
     <x>450</x>
     <y>90</y>
     <width>64</width>
     <height>20</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 255, 127);
color: rgb(0, 85, 0);</string>
   </property>
   <property name="segmentStyle">
    <enum>QLCDNumber::Flat</enum>
   </property>
  </widget>
  <widget class="QLabel" name="labelTx">
   <property name="geometry">
    <rect>
     <x>520</x>
     <y>40</y>
     <width>20</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Tx</string>
   </property>
  </widget>
  <widget class="QLabel" name="labelTz">
   <property name="geometry">
    <rect>
     <x>520</x>
     <y>100</y>
     <width>20</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Tz</string>
   </property>
  </widget>
  <widget class="QLabel" name="labelTy">
   <property name="geometry">
    <rect>
     <x>520</x>
     <y>70</y>
     <width>20</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>Ty</string>
   </property>
  </widget>
  <widget class="QLCDNumber" name="lcdNumberTx">
   <property name="geometry">
    <rect>
     <x>450</x>
     <y>30</y>
     <width>64</width>
     <height>20</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 255, 127);
color: rgb(0, 85, 0);</string>
   </property>
   <property name="segmentStyle">
    <enum>QLCDNumber::Flat</enum>
   </property>
  </widget>
  <widget class="QLCDNumber" name="lcdNumberTy">
   <property name="geometry">
    <rect>
     <x>450</x>
     <y>60</y>
     <width>64</width>
     <height>20</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color: rgb(170, 255, 127);
color: rgb(0, 85, 0);</string>
   </property>
   <property name="segmentStyle">
    <enum>QLCDNumber::Flat</enum>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButtonRAZ">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>230</y>
     <width>85</width>
     <height>20</height>
    </rect>
   </property>
   <property name="text">
    <string>RAZ</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
 <designerdata>
  <property name="gridDeltaX">
   <number>10</number>
  </property>
  <property name="gridDeltaY">
   <number>10</number>
  </property>
  <property name="gridSnapX">
   <bool>true</bool>
  </property>
  <property name="gridSnapY">
   <bool>true</bool>
  </property>
  <property name="gridVisible">
   <bool>true</bool>
  </property>
 </designerdata>
</ui>

 

Le fichier d'interface *.py

  • Fichier obtenu automatiquement avec l'utilitaire pyuic4 à partir du fichier *.ui créé avec QtDesigner :

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file
#
# Created: Mon Aug 19 15:49:52 2013
#      by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(540, 365)
        self.horizontalLayoutWidget = QtGui.QWidget(Form)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 320, 240))
        self.horizontalLayoutWidget.setObjectName(_fromUtf8("horizontalLayoutWidget"))
        self.horizontalLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setMargin(0)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.labelTranslation = QtGui.QLabel(Form)
        self.labelTranslation.setGeometry(QtCore.QRect(340, 10, 81, 13))
        self.labelTranslation.setObjectName(_fromUtf8("labelTranslation"))
        self.lineEditTx = QtGui.QLineEdit(Form)
        self.lineEditTx.setGeometry(QtCore.QRect(370, 30, 45, 20))
        self.lineEditTx.setObjectName(_fromUtf8("lineEditTx"))
        self.pushButtonTxMoins = QtGui.QPushButton(Form)
        self.pushButtonTxMoins.setGeometry(QtCore.QRect(340, 30, 23, 20))
        self.pushButtonTxMoins.setObjectName(_fromUtf8("pushButtonTxMoins"))
        self.pushButtonTxPlus = QtGui.QPushButton(Form)
        self.pushButtonTxPlus.setGeometry(QtCore.QRect(420, 30, 23, 20))
        self.pushButtonTxPlus.setObjectName(_fromUtf8("pushButtonTxPlus"))
        self.pushButtonTyMoins = QtGui.QPushButton(Form)
        self.pushButtonTyMoins.setGeometry(QtCore.QRect(340, 60, 23, 20))
        self.pushButtonTyMoins.setObjectName(_fromUtf8("pushButtonTyMoins"))
        self.pushButtonTyPlus = QtGui.QPushButton(Form)
        self.pushButtonTyPlus.setGeometry(QtCore.QRect(420, 60, 23, 20))
        self.pushButtonTyPlus.setObjectName(_fromUtf8("pushButtonTyPlus"))
        self.lineEditTy = QtGui.QLineEdit(Form)
        self.lineEditTy.setGeometry(QtCore.QRect(370, 60, 45, 20))
        self.lineEditTy.setObjectName(_fromUtf8("lineEditTy"))
        self.pushButtonTzMoins = QtGui.QPushButton(Form)
        self.pushButtonTzMoins.setGeometry(QtCore.QRect(340, 90, 23, 20))
        self.pushButtonTzMoins.setObjectName(_fromUtf8("pushButtonTzMoins"))
        self.pushButtonTzPlus = QtGui.QPushButton(Form)
        self.pushButtonTzPlus.setGeometry(QtCore.QRect(420, 90, 23, 20))
        self.pushButtonTzPlus.setObjectName(_fromUtf8("pushButtonTzPlus"))
        self.lineEditTz = QtGui.QLineEdit(Form)
        self.lineEditTz.setGeometry(QtCore.QRect(370, 90, 45, 20))
        self.lineEditTz.setObjectName(_fromUtf8("lineEditTz"))
        self.pushButtonRxMoins = QtGui.QPushButton(Form)
        self.pushButtonRxMoins.setGeometry(QtCore.QRect(340, 140, 23, 20))
        self.pushButtonRxMoins.setObjectName(_fromUtf8("pushButtonRxMoins"))
        self.lineEditRy = QtGui.QLineEdit(Form)
        self.lineEditRy.setGeometry(QtCore.QRect(370, 170, 45, 20))
        self.lineEditRy.setObjectName(_fromUtf8("lineEditRy"))
        self.pushButtonRxPlus = QtGui.QPushButton(Form)
        self.pushButtonRxPlus.setGeometry(QtCore.QRect(420, 140, 23, 20))
        self.pushButtonRxPlus.setObjectName(_fromUtf8("pushButtonRxPlus"))
        self.pushButtonRzMoins = QtGui.QPushButton(Form)
        self.pushButtonRzMoins.setGeometry(QtCore.QRect(340, 200, 23, 20))
        self.pushButtonRzMoins.setObjectName(_fromUtf8("pushButtonRzMoins"))
        self.pushButtonRzPlus = QtGui.QPushButton(Form)
        self.pushButtonRzPlus.setGeometry(QtCore.QRect(420, 200, 23, 20))
        self.pushButtonRzPlus.setObjectName(_fromUtf8("pushButtonRzPlus"))
        self.lineEditRz = QtGui.QLineEdit(Form)
        self.lineEditRz.setGeometry(QtCore.QRect(370, 200, 45, 20))
        self.lineEditRz.setObjectName(_fromUtf8("lineEditRz"))
        self.labelRotation = QtGui.QLabel(Form)
        self.labelRotation.setGeometry(QtCore.QRect(340, 120, 81, 13))
        self.labelRotation.setObjectName(_fromUtf8("labelRotation"))
        self.pushButtonRyMoins = QtGui.QPushButton(Form)
        self.pushButtonRyMoins.setGeometry(QtCore.QRect(340, 170, 23, 20))
        self.pushButtonRyMoins.setObjectName(_fromUtf8("pushButtonRyMoins"))
        self.lineEditRx = QtGui.QLineEdit(Form)
        self.lineEditRx.setGeometry(QtCore.QRect(370, 140, 45, 20))
        self.lineEditRx.setObjectName(_fromUtf8("lineEditRx"))
        self.pushButtonRyPlus = QtGui.QPushButton(Form)
        self.pushButtonRyPlus.setGeometry(QtCore.QRect(420, 170, 23, 20))
        self.pushButtonRyPlus.setObjectName(_fromUtf8("pushButtonRyPlus"))
        self.lcdNumberRx = QtGui.QLCDNumber(Form)
        self.lcdNumberRx.setGeometry(QtCore.QRect(450, 140, 64, 20))
        self.lcdNumberRx.setStyleSheet(_fromUtf8("background-color: rgb(170, 255, 127);\n"
"color: rgb(0, 85, 0);"))
        self.lcdNumberRx.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberRx.setObjectName(_fromUtf8("lcdNumberRx"))
        self.labelRx = QtGui.QLabel(Form)
        self.labelRx.setGeometry(QtCore.QRect(520, 150, 20, 13))
        self.labelRx.setObjectName(_fromUtf8("labelRx"))
        self.labelRy = QtGui.QLabel(Form)
        self.labelRy.setGeometry(QtCore.QRect(520, 180, 20, 13))
        self.labelRy.setObjectName(_fromUtf8("labelRy"))
        self.lcdNumberRy = QtGui.QLCDNumber(Form)
        self.lcdNumberRy.setGeometry(QtCore.QRect(450, 170, 64, 20))
        self.lcdNumberRy.setStyleSheet(_fromUtf8("background-color: rgb(170, 255, 127);\n"
"color: rgb(0, 85, 0);"))
        self.lcdNumberRy.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberRy.setObjectName(_fromUtf8("lcdNumberRy"))
        self.labelRz = QtGui.QLabel(Form)
        self.labelRz.setGeometry(QtCore.QRect(520, 210, 20, 13))
        self.labelRz.setObjectName(_fromUtf8("labelRz"))
        self.lcdNumberRz = QtGui.QLCDNumber(Form)
        self.lcdNumberRz.setGeometry(QtCore.QRect(450, 200, 64, 20))
        self.lcdNumberRz.setStyleSheet(_fromUtf8("background-color: rgb(170, 255, 127);\n"
"color: rgb(0, 85, 0);"))
        self.lcdNumberRz.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberRz.setObjectName(_fromUtf8("lcdNumberRz"))
        self.lcdNumberTz = QtGui.QLCDNumber(Form)
        self.lcdNumberTz.setGeometry(QtCore.QRect(450, 90, 64, 20))
        self.lcdNumberTz.setStyleSheet(_fromUtf8("background-color: rgb(170, 255, 127);\n"
"color: rgb(0, 85, 0);"))
        self.lcdNumberTz.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberTz.setObjectName(_fromUtf8("lcdNumberTz"))
        self.labelTx = QtGui.QLabel(Form)
        self.labelTx.setGeometry(QtCore.QRect(520, 40, 20, 13))
        self.labelTx.setObjectName(_fromUtf8("labelTx"))
        self.labelTz = QtGui.QLabel(Form)
        self.labelTz.setGeometry(QtCore.QRect(520, 100, 20, 13))
        self.labelTz.setObjectName(_fromUtf8("labelTz"))
        self.labelTy = QtGui.QLabel(Form)
        self.labelTy.setGeometry(QtCore.QRect(520, 70, 20, 13))
        self.labelTy.setObjectName(_fromUtf8("labelTy"))
        self.lcdNumberTx = QtGui.QLCDNumber(Form)
        self.lcdNumberTx.setGeometry(QtCore.QRect(450, 30, 64, 20))
        self.lcdNumberTx.setStyleSheet(_fromUtf8("background-color: rgb(170, 255, 127);\n"
"color: rgb(0, 85, 0);"))
        self.lcdNumberTx.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberTx.setObjectName(_fromUtf8("lcdNumberTx"))
        self.lcdNumberTy = QtGui.QLCDNumber(Form)
        self.lcdNumberTy.setGeometry(QtCore.QRect(450, 60, 64, 20))
        self.lcdNumberTy.setStyleSheet(_fromUtf8("background-color: rgb(170, 255, 127);\n"
"color: rgb(0, 85, 0);"))
        self.lcdNumberTy.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberTy.setObjectName(_fromUtf8("lcdNumberTy"))
        self.pushButtonRAZ = QtGui.QPushButton(Form)
        self.pushButtonRAZ.setGeometry(QtCore.QRect(350, 230, 85, 20))
        self.pushButtonRAZ.setObjectName(_fromUtf8("pushButtonRAZ"))

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "pyqt + openGL : translation/rotation du repère 3D de base", None, QtGui.QApplication.UnicodeUTF8))
        self.labelTranslation.setText(QtGui.QApplication.translate("Form", "Translation :", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditTx.setText(QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonTxMoins.setText(QtGui.QApplication.translate("Form", "-X", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonTxPlus.setText(QtGui.QApplication.translate("Form", "+X", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonTyMoins.setText(QtGui.QApplication.translate("Form", "-Y", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonTyPlus.setText(QtGui.QApplication.translate("Form", "+Y", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditTy.setText(QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonTzMoins.setText(QtGui.QApplication.translate("Form", "-Z", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonTzPlus.setText(QtGui.QApplication.translate("Form", "+Z", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditTz.setText(QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRxMoins.setText(QtGui.QApplication.translate("Form", "-X", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditRy.setText(QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRxPlus.setText(QtGui.QApplication.translate("Form", "+X", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRzMoins.setText(QtGui.QApplication.translate("Form", "-Z", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRzPlus.setText(QtGui.QApplication.translate("Form", "+Z", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditRz.setText(QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8))
        self.labelRotation.setText(QtGui.QApplication.translate("Form", "Rotation", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRyMoins.setText(QtGui.QApplication.translate("Form", "-Y", None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditRx.setText(QtGui.QApplication.translate("Form", "10", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRyPlus.setText(QtGui.QApplication.translate("Form", "+Y", None, QtGui.QApplication.UnicodeUTF8))
        self.labelRx.setText(QtGui.QApplication.translate("Form", "Rx", None, QtGui.QApplication.UnicodeUTF8))
        self.labelRy.setText(QtGui.QApplication.translate("Form", "Ry", None, QtGui.QApplication.UnicodeUTF8))
        self.labelRz.setText(QtGui.QApplication.translate("Form", "Rz", None, QtGui.QApplication.UnicodeUTF8))
        self.labelTx.setText(QtGui.QApplication.translate("Form", "Tx", None, QtGui.QApplication.UnicodeUTF8))
        self.labelTz.setText(QtGui.QApplication.translate("Form", "Tz", None, QtGui.QApplication.UnicodeUTF8))
        self.labelTy.setText(QtGui.QApplication.translate("Form", "Ty", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonRAZ.setText(QtGui.QApplication.translate("Form", "RAZ", None, QtGui.QApplication.UnicodeUTF8))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

 

Le fichier d'application *Main.py


#!/usr/bin/python
# -*- coding: utf-8 -*-

# par X. HINAULT - Nov 2012 - Tous droits réservés
# GPLv3 - www.mon-club-elec.fr

# Implémentation de base d'OpenGL dans une interface Qt

# modules a importer
from PyQt4.QtGui import *
from PyQt4.QtCore import *  # inclut QTimer..
from PyQt4.QtOpenGL import *

from OpenGL.GL import * # si format glfonction
#from OpenGL import GL # si format GL.glfonction
from OpenGL.GLU import * # librairie associée à OpenGL
#from OpenGL.GLUT import * # librairie associée à OpenGL

import os,sys
import math, random

from tuto_pyqt_openGL_repere_base_buttons import * # fichier obtenu à partir QtDesigner et pyuic4

# déclaration de variables globales
Tx=0 # variable translation courante axe des X
Ty=0 # variable translation courante axe des X
Tz=0 # variable translation courante axe des X

Rx=0 # variable rotation courante axe des X
Ry=0 # variable rotation courante axe des X
Rz=0 # variable rotation courante axe des X

class myApp(QWidget, Ui_Form): # la classe reçoit le Qwidget principal ET la classe définie dans test.py obtenu avec pyuic4
        def __init__(self, parent=None):
                QWidget.__init__(self) # initialise le Qwidget principal
                self.setupUi(parent) # Obligatoire

                # intégration d'opengl dans l'interface graphique QT designer
                self.glWidget = myGLWidget() # déclare un objet de la classe locale issue de QGLWidget - voir ci-dessous               
                self.horizontalLayout.addWidget(self.glWidget) # ajoute le GLWidget au HLayout prévu dans QtDesigner

                #Ici, personnalisez vos widgets si nécessaire

                #-- pushButton translation --
                self.connect(self.pushButtonTxMoins, SIGNAL("clicked()"), self.pushButtonTxMoinsClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonTyMoins, SIGNAL("clicked()"), self.pushButtonTyMoinsClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonTzMoins, SIGNAL("clicked()"), self.pushButtonTzMoinsClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                self.connect(self.pushButtonTxPlus, SIGNAL("clicked()"), self.pushButtonTxPlusClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonTyPlus, SIGNAL("clicked()"), self.pushButtonTyPlusClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonTzPlus, SIGNAL("clicked()"), self.pushButtonTzPlusClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                #-- pushButton rotation --
                self.connect(self.pushButtonRxMoins, SIGNAL("clicked()"), self.pushButtonRxMoinsClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonRyMoins, SIGNAL("clicked()"), self.pushButtonRyMoinsClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonRzMoins, SIGNAL("clicked()"), self.pushButtonRzMoinsClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                self.connect(self.pushButtonRxPlus, SIGNAL("clicked()"), self.pushButtonRxPlusClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonRyPlus, SIGNAL("clicked()"), self.pushButtonRyPlusClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue
                self.connect(self.pushButtonRzPlus, SIGNAL("clicked()"), self.pushButtonRzPlusClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                self.connect(self.pushButtonRAZ, SIGNAL("clicked()"), self.pushButtonRAZClicked) # connecte le signal Clicked de l'objet bouton à l'appel de la fonction voulue

                #Réalisez les connexions supplémentaires entre signaux et slots

                # autres objets à déclarer à l'initialisation
                #self.timer=QTimer() # déclare un QTimer
                #self.timer.start(10) # démarre le QTimer à n ms
                #self.connect(self.timer, SIGNAL("timeout()"), self.timerEvent) # connecte le signal timeOut de l'objet timer à l'appel de la fonction voulue

        # les fonctions appelées, utilisées par les signaux
        #def timerEvent(self): # fonction appelée lors de la survenue d'un évènement Timer - nom fonction indiférrent
                #print("Timer")
                #self.glWidget.update() # actualise le dessin openGl

        #======== fonctions des pushButton =========
        # -- pushButton translation
        def pushButtonTxMoinsClicked(self):
                print("Bouton Tx Moins appuyé")
                global Tx
                Tx=Tx-int(self.lineEditTx.text())
                self.lcdNumberTx.display(Tx) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonTyMoinsClicked(self):
                print("Bouton Ty Moins appuyé")
                global Ty
                Ty=Ty-int(self.lineEditTy.text())
                self.lcdNumberTy.display(Ty) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonTzMoinsClicked(self):
                print("Bouton Tz Moins appuyé")
                global Tz
                Tz=Tz-int(self.lineEditTz.text())
                self.lcdNumberTz.display(Tz) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonTxPlusClicked(self):
                print("Bouton Tx Plus appuyé")
                global Tx
                Tx=Tx+int(self.lineEditTx.text())
                self.lcdNumberTx.display(Tx) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonTyPlusClicked(self):
                print("Bouton Ty Plus appuyé")
                global Ty
                Ty=Ty+int(self.lineEditTy.text())
                self.lcdNumberTy.display(Ty) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonTzPlusClicked(self):
                print("Bouton Tz Plus appuyé")
                global Tz
                Tz=Tz+int(self.lineEditTz.text())
                self.lcdNumberTz.display(Tz) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        # -- pushButton Rotation
        def pushButtonRxMoinsClicked(self):
                print("Bouton Rx Moins appuyé")
                global Rx
                Rx=Rx-int(self.lineEditRx.text())
                self.lcdNumberRx.display(Rx) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonRyMoinsClicked(self):
                print("Bouton Ry Moins appuyé")
                global Ry
                Ry=Ry-int(self.lineEditRy.text())
                self.lcdNumberRy.display(Ry) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonRzMoinsClicked(self):
                print("Bouton Rz Moins appuyé")
                global Rz
                Rz=Rz-int(self.lineEditRz.text())
                self.lcdNumberRz.display(Rz) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonRxPlusClicked(self):
                print("Bouton Rx Plus appuyé")
                global Rx
                Rx=Rx+int(self.lineEditRx.text())
                self.lcdNumberRx.display(Rx) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonRyPlusClicked(self):
                print("Bouton Ry Plus appuyé")
                global Ry
                Ry=Ry+int(self.lineEditRy.text())
                self.lcdNumberRy.display(Ry) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonRzPlusClicked(self):
                print("Bouton Rz Plus appuyé")
                global Rz
                Rz=Rz+int(self.lineEditRz.text())
                self.lcdNumberRz.display(Rz) # MAJ des lcdNumber
                self.glWidget.update() # actualise le dessin openGl

        def pushButtonRAZClicked(self):
                print("Bouton RAZ appuyé")
                global Tx,Ty,Tz,Rx,Ry,Rz
                Tx=0
                Ty=0
                Tz=0
                Rx=0
                Ry=0
                Rz=0

                self.lcdNumberTx.display(Tx) # MAJ des lcdNumber
                self.lcdNumberTy.display(Ty) # MAJ des lcdNumber
                self.lcdNumberTz.display(Tz) # MAJ des lcdNumber

                self.lcdNumberRx.display(Rx) # MAJ des lcdNumber
                self.lcdNumberRy.display(Ry) # MAJ des lcdNumber
                self.lcdNumberRz.display(Rz) # MAJ des lcdNumber

                self.glWidget.update() # actualise le dessin openGl

#-- fin de la classe principale myApp

class myGLWidget(QGLWidget): # classe locale issue de QGLWidget et redéfinissant les fonctions virtuelles du QGLWidget
        def __init__(self, parent=None): # constructeur
                QGLWidget.__init__(self, parent) # base la classe locale sur la classe QGLWidget

        #ici les fonctions propres du QGLWidget local

        def paintGL(self): # fonction de rafraîchissement - doit être appelée par updateGL() via QTimer au besoin
                print("Mise à jour fenêtre OpenGL")

                global Tx,Ty,Tz,Rx,Ry,Rz
                # RAZ des angles
                if Rx>359:
                        Rx=0
                if Ry>359:
                        Ry=0
                if Rz>359:
                        Rz=0

                print("Tx:"+str(Tx)+" Ty:"+str(Ty)+" Tz:"+str(Tz)+ " Rx:"+str(Rx)+ " Ry:"+str(Ry)+ " Rz:"+str(Rz))

                #---- paramètres généraux ----

                #------- fixe la couleur de fond de la fenêtre -----
                glClearColor(0.0, 0.0, 0.0, 1.0) # couleur d'arrière plan
                glClear(GL_COLOR_BUFFER_BIT) # efface le fond  

                #glEnable(GL_DEPTH_TEST) # active le test de profondeur pour éviter voir faces cachées

                #-------- définition de la perspective utilisée -----
                glMatrixMode(GL_PROJECTION) # sélectionne la matrice de projection
                glLoadIdentity() # charge la matrice identité

                print("Matrice de projection :")
                print (glGetFloatv( GL_PROJECTION_MATRIX )) # affiche la matrice de projection courante

                #gluPerspective( angle, ratio, near, far )
                gluPerspective( 60, 320.0/240.0, 0, -1000 ) # définit la perspective

                print("Matrice de projection :")
                print (glGetFloatv( GL_PROJECTION_MATRIX )) # affiche la matrice de projection courante

                #---- définition de l'angle de vue de la caméra ----
                # par défaut la caméra se trouve en 0,0,0 et regarde vers l'axe Z-
                #gluLookAt (0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0) # valeur par défaut
                #gluLookAt (0.0, 0.0, -200, 0.0, 0.0, -1000.0, 0.0, 1.0, 0.0) # positionne la caméra


                #--- fixe la taille de la fenêtre de visualisation
                glViewport(0, 0, 320, 240) # fixe l'origine et la taille de la fenêtre de visualisation
                # utiliser un ratio idem celui de la perspective
                # utiliser la même taille que la fenêtre d'affichage à l'écran

                #-------- dessin du modèle 3D -----

                glMatrixMode(GL_MODELVIEW) # sélectionne la matrice de vue du modèle
                glLoadIdentity() # charge la matrice identité
                # sinon c'est la matrice courante qui est utilisée et les modif s'ajoutent aux modif déjà réalisées

                print("Matrice de vue du modèle :")
                print (glGetFloatv( GL_MODELVIEW_MATRIX )) # affiche la matrice courante

                # -- positionnement du repère de la fenêtre de visualisation
                self.Zo=-207.84 # définition de la valeur Zo
                # Zo est en fait la position en Z telle que x,y correspondent à la taille de la fenêtre de l'écran...
                glTranslate(0+Tx,0+Ty,self.Zo+Tz) # translation en (0,0,Zo)

                glRotate(Rx,1,0,0) # rotation axe X
                glRotate(Ry,0,1,0) # rotation axe Y
                glRotate(Rz,0,0,1) # rotation axe Z

                #-- réaffichage des matrices avant de dessiner --
                print("Matrice de projection :")
                print (glGetFloatv( GL_PROJECTION_MATRIX )) # affiche la matrice courante avant dessin
                print("Matrice de vue du modèle :")
                print (glGetFloatv( GL_MODELVIEW_MATRIX )) # affiche la matrice courante avant dessin

                # --- dessine le point O(0,0,0)
                glPointSize(5) # fixe la taille des points

                glBegin(GL_POINTS) # début du dessin - mode lignes
                glColor3ub(255,255,0) # jaune
                glVertex3d(0,0,0)
                glEnd()

                # dessin à réaliser
                glColor3ub(255,255,0) # jaune  
                #gluSphere(self.quadratic,1,20,20) # tracé d'une sphère
                gluDisk(self.quadratic,0,75,24,10) # tracé d'un disque
                #gluPartialDisk(self.quadratic,0,75,16,10,60,240)

                # --- dessine le repère 3D Oxyz - en dernier = par dessus le reste
                glBegin(GL_LINES) # début du dessin - mode lignes

                taille=100             
                # Ox
                glColor3ub(255,0,0) # rouge
                glVertex3d(0,0,0)
                glVertex3d(taille,0,0)         

                # Oy
                glColor3ub(0,255,0) # vert
                glVertex3d(0,0,0)
                glVertex3d(0,taille,0)         

                # Oz
                glColor3ub(0,0,255) # bleu
                glVertex3d(0,0,0)
                glVertex3d(0,0,taille)         

                glEnd() # fin du dessin


        def resizeGL(self, w, h): # fonction appelée pour redimensionnement (et au 1er lancement)
        # et lors de chaque recouvrement de la fenêtre par une autre, etc...
                print("Redimensionnement fenêtre OpenGL")

        def initializeGL(self): # fonction d'initialisation de la fenêtre openGL
                print("Initialisation openGL")

                # déclaration d'un objet quadrique
                self.quadratic = gluNewQuadric() # déclaration d'un quadratique = forme 3D
                gluQuadricDrawStyle(self.quadratic,GLU_LINE) # fixe le mode de dessin
                #gluQuadricDrawStyle(self.quadratic,GLU_FILL) # fixe le mode de dessin


        # gestion des évènements
        def mousePressEvent(self, event):
                print("Appui souris")
                #self.updateGL() # appelle paintGL

# fin class myGLWidget

# code rendant l'application exécutable  
def main(args):
        a=QApplication(args) # crée l'objet application
        f=QWidget() # crée le QWidget racine
        c=myApp(f) # appelle la classe contenant le code de l'application
        f.show() # affiche la fenêtre QWidget
        r=a.exec_() # lance l'exécution de l'application
        return r

if __name__=="__main__": # pour rendre le code exécutable
        main(sys.argv) # appelle la fonction main

 

Utilisation

  • Les 2 fichiers suivants sont à enregistrer dans un même répertoire, l'un en nom.py et l'autre en nomMain.py.
  • Puis lancer l'application depuis Geany ou équivalent, en exécutant le fichier nomMain.py