Logo Mon Club Elec

PyQt Lab’ : Graphiques Math : Pyqtgraph : Affichage progressif d’une courbe dans un graphique Pyqtgraph avec bouton de Stop, bouton Effacer, bouton réglage vitesse et lcdNumber d’affichage.

PyQt Lab’ : Graphiques Math : Pyqtgraph : Affichage progressif d’une courbe dans un graphique Pyqtgraph avec bouton de Stop, bouton Effacer, bouton réglage vitesse et lcdNumber d’affichage.

Par X. HINAULT – Juin 2013

PyQt Lab’ : Graphiques Math : Pyqtgraph : Affichage progressif d’une courbe dans un graphique Pyqtgraph avec bouton de Stop, bouton Effacer, bouton réglage vitesse et lcdNumber d’affichage.

Ce que l’on va faire ici

  • Affichage progressif d’une courbe dans un graphique Pyqtgraph avec bouton de Stop, bouton Effacer, bouton réglage vitesse et lcdNumber d’affichage.

Pré-requis

  • python 2.7
  • pyqt4.x
  • pyqtgraph

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>658</width>
    <height>413</height>
   </rect>
  </property>
  <property name=« windowTitle »>
   <string>PyQt + pyqtgraph : Affichage courbe progressive avec stop, lcdNumber</string>
  </property>
  <widget class=« PlotWidget » name=« graph »>
   <property name=« geometry »>
    <rect>
     <x>5</x>
     <y>10</y>
     <width>480</width>
     <height>360</height>
    </rect>
   </property>
  </widget>
  <widget class=« QLineEdit » name=« lineEditValeurMin »>
   <property name=« geometry »>
    <rect>
     <x>500</x>
     <y>80</y>
     <width>66</width>
     <height>23</height>
    </rect>
   </property>
   <property name=« text »>
    <string>-1000</string>
   </property>
  </widget>
  <widget class=« QLabel » name=« labelUnite »>
   <property name=« geometry »>
    <rect>
     <x>595</x>
     <y>130</y>
     <width>51</width>
     <height>13</height>
    </rect>
   </property>
   <property name=« text »>
    <string>Unité :</string>
   </property>
  </widget>
  <widget class=« QLCDNumber » name=« lcdNumberValeurBrute »>
   <property name=« geometry »>
    <rect>
     <x>495</x>
     <y>25</y>
     <width>96</width>
     <height>36</height>
    </rect>
   </property>
   <property name=« styleSheet »>
    <string notr=« true »>background-color: rgb(170, 255, 127);
color: rgb(0, 170, 0);</string>
   </property>
   <property name=« smallDecimalPoint »>
    <bool>false</bool>
   </property>
  </widget>
  <widget class=« QLabel » name=« labelValeurCalc »>
   <property name=« geometry »>
    <rect>
     <x>500</x>
     <y>110</y>
     <width>106</width>
     <height>16</height>
    </rect>
   </property>
   <property name=« text »>
    <string>Valeur calculée :</string>
   </property>
  </widget>
  <widget class=« QLineEdit » name=« lineEditValeurMax »>
   <property name=« geometry »>
    <rect>
     <x>575</x>
     <y>80</y>
     <width>66</width>
     <height>23</height>
    </rect>
   </property>
   <property name=« text »>
    <string>+1000</string>
   </property>
  </widget>
  <widget class=« QLabel » name=« labelDelaiMesure »>
   <property name=« geometry »>
    <rect>
     <x>510</x>
     <y>265</y>
     <width>71</width>
     <height>16</height>
    </rect>
   </property>
   <property name=« text »>
    <string>delai ms</string>
   </property>
  </widget>
  <widget class=« QLabel » name=« labelValeurBrute »>
   <property name=« geometry »>
    <rect>
     <x>495</x>
     <y>10</y>
     <width>81</width>
     <height>16</height>
    </rect>
   </property>
   <property name=« text »>
    <string>Valeur brute :</string>
   </property>
  </widget>
  <widget class=« QLabel » name=« labelValeurMin »>
   <property name=« geometry »>
    <rect>
     <x>500</x>
     <y>65</y>
     <width>71</width>
     <height>16</height>
    </rect>
   </property>
   <property name=« text »>
    <string>Valeur mini</string>
   </property>
  </widget>
  <widget class=« QLCDNumber » name=« lcdNumberValeurCalc »>
   <property name=« geometry »>
    <rect>
     <x>495</x>
     <y>130</y>
     <width>96</width>
     <height>36</height>
    </rect>
   </property>
   <property name=« styleSheet »>
    <string notr=« true »>background-color: rgb(255, 255, 0);
color: rgb(255, 0, 0);</string>
   </property>
   <property name=« smallDecimalPoint »>
    <bool>true</bool>
   </property>
   <property name=« mode »>
    <enum>QLCDNumber::Dec</enum>
   </property>
  </widget>
  <widget class=« QDial » name=« dialDelaiMesure »>
   <property name=« geometry »>
    <rect>
     <x>505</x>
     <y>175</y>
     <width>50</width>
     <height>64</height>
    </rect>
   </property>
   <property name=« minimum »>
    <number>0</number>
   </property>
   <property name=« maximum »>
    <number>8</number>
   </property>
   <property name=« value »>
    <number>4</number>
   </property>
   <property name=« notchesVisible »>
    <bool>true</bool>
   </property>
  </widget>
  <widget class=« QPushButton » name=« pushRadioButtonStop »>
   <property name=« geometry »>
    <rect>
     <x>575</x>
     <y>240</y>
     <width>66</width>
     <height>27</height>
    </rect>
   </property>
   <property name=« text »>
    <string>STOP</string>
   </property>
   <property name=« checkable »>
    <bool>true</bool>
   </property>
  </widget>
  <widget class=« QLabel » name=« labelValeurMax »>
   <property name=« geometry »>
    <rect>
     <x>575</x>
     <y>65</y>
     <width>71</width>
     <height>16</height>
    </rect>
   </property>
   <property name=« text »>
    <string>Valeur maxi</string>
   </property>
  </widget>
  <widget class=« QLineEdit » name=« lineEditUnite »>
   <property name=« geometry »>
    <rect>
     <x>595</x>
     <y>145</y>
     <width>56</width>
     <height>23</height>
    </rect>
   </property>
   <property name=« text »>
    <string>U</string>
   </property>
  </widget>
  <widget class=« QLCDNumber » name=« lcdNumberDelaiMesure »>
   <property name=« geometry »>
    <rect>
     <x>500</x>
     <y>240</y>
     <width>64</width>
     <height>23</height>
    </rect>
   </property>
   <property name=« styleSheet »>
    <string notr=« true »>background-color: rgb(255, 255, 147);
color: rgb(0, 85, 255);</string>
   </property>
   <property name=« midLineWidth »>
    <number>0</number>
   </property>
   <property name=« segmentStyle »>
    <enum>QLCDNumber::Flat</enum>
   </property>
   <property name=« value » stdset=« 0 »>
    <double>0.000000000000000</double>
   </property>
  </widget>
  <widget class=« QPushButton » name=« pushButtonEffacer »>
   <property name=« geometry »>
    <rect>
     <x>575</x>
     <y>195</y>
     <width>66</width>
     <height>27</height>
    </rect>
   </property>
   <property name=« text »>
    <string>Effacer</string>
   </property>
  </widget>
 </widget>
 <customwidgets>
  <customwidget>
   <class>PlotWidget</class>
   <extends>QGraphicsView</extends>
   <header>pyqtgraph</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</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: Sun Aug 18 15:02:46 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(658, 413)
        self.graph = PlotWidget(Form)
        self.graph.setGeometry(QtCore.QRect(5, 10, 480, 360))
        self.graph.setObjectName(_fromUtf8(« graph »))
        self.lineEditValeurMin = QtGui.QLineEdit(Form)
        self.lineEditValeurMin.setGeometry(QtCore.QRect(500, 80, 66, 23))
        self.lineEditValeurMin.setObjectName(_fromUtf8(« lineEditValeurMin »))
        self.labelUnite = QtGui.QLabel(Form)
        self.labelUnite.setGeometry(QtCore.QRect(595, 130, 51, 13))
        self.labelUnite.setObjectName(_fromUtf8(« labelUnite »))
        self.lcdNumberValeurBrute = QtGui.QLCDNumber(Form)
        self.lcdNumberValeurBrute.setGeometry(QtCore.QRect(495, 25, 96, 36))
        self.lcdNumberValeurBrute.setStyleSheet(_fromUtf8(« background-color: rgb(170, 255, 127);\n« 
« color: rgb(0, 170, 0); »))
        self.lcdNumberValeurBrute.setSmallDecimalPoint(False)
        self.lcdNumberValeurBrute.setObjectName(_fromUtf8(« lcdNumberValeurBrute »))
        self.labelValeurCalc = QtGui.QLabel(Form)
        self.labelValeurCalc.setGeometry(QtCore.QRect(500, 110, 106, 16))
        self.labelValeurCalc.setObjectName(_fromUtf8(« labelValeurCalc »))
        self.lineEditValeurMax = QtGui.QLineEdit(Form)
        self.lineEditValeurMax.setGeometry(QtCore.QRect(575, 80, 66, 23))
        self.lineEditValeurMax.setObjectName(_fromUtf8(« lineEditValeurMax »))
        self.labelDelaiMesure = QtGui.QLabel(Form)
        self.labelDelaiMesure.setGeometry(QtCore.QRect(510, 265, 71, 16))
        self.labelDelaiMesure.setObjectName(_fromUtf8(« labelDelaiMesure »))
        self.labelValeurBrute = QtGui.QLabel(Form)
        self.labelValeurBrute.setGeometry(QtCore.QRect(495, 10, 81, 16))
        self.labelValeurBrute.setObjectName(_fromUtf8(« labelValeurBrute »))
        self.labelValeurMin = QtGui.QLabel(Form)
        self.labelValeurMin.setGeometry(QtCore.QRect(500, 65, 71, 16))
        self.labelValeurMin.setObjectName(_fromUtf8(« labelValeurMin »))
        self.lcdNumberValeurCalc = QtGui.QLCDNumber(Form)
        self.lcdNumberValeurCalc.setGeometry(QtCore.QRect(495, 130, 96, 36))
        self.lcdNumberValeurCalc.setStyleSheet(_fromUtf8(« background-color: rgb(255, 255, 0);\n« 
« color: rgb(255, 0, 0); »))
        self.lcdNumberValeurCalc.setSmallDecimalPoint(True)
        self.lcdNumberValeurCalc.setMode(QtGui.QLCDNumber.Dec)
        self.lcdNumberValeurCalc.setObjectName(_fromUtf8(« lcdNumberValeurCalc »))
        self.dialDelaiMesure = QtGui.QDial(Form)
        self.dialDelaiMesure.setGeometry(QtCore.QRect(505, 175, 50, 64))
        self.dialDelaiMesure.setMinimum(0)
        self.dialDelaiMesure.setMaximum(8)
        self.dialDelaiMesure.setProperty(« value », 4)
        self.dialDelaiMesure.setNotchesVisible(True)
        self.dialDelaiMesure.setObjectName(_fromUtf8(« dialDelaiMesure »))
        self.pushRadioButtonStop = QtGui.QPushButton(Form)
        self.pushRadioButtonStop.setGeometry(QtCore.QRect(575, 240, 66, 27))
        self.pushRadioButtonStop.setCheckable(True)
        self.pushRadioButtonStop.setObjectName(_fromUtf8(« pushRadioButtonStop »))
        self.labelValeurMax = QtGui.QLabel(Form)
        self.labelValeurMax.setGeometry(QtCore.QRect(575, 65, 71, 16))
        self.labelValeurMax.setObjectName(_fromUtf8(« labelValeurMax »))
        self.lineEditUnite = QtGui.QLineEdit(Form)
        self.lineEditUnite.setGeometry(QtCore.QRect(595, 145, 56, 23))
        self.lineEditUnite.setObjectName(_fromUtf8(« lineEditUnite »))
        self.lcdNumberDelaiMesure = QtGui.QLCDNumber(Form)
        self.lcdNumberDelaiMesure.setGeometry(QtCore.QRect(500, 240, 64, 23))
        self.lcdNumberDelaiMesure.setStyleSheet(_fromUtf8(« background-color: rgb(255, 255, 147);\n« 
« color: rgb(0, 85, 255); »))
        self.lcdNumberDelaiMesure.setMidLineWidth(0)
        self.lcdNumberDelaiMesure.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.lcdNumberDelaiMesure.setProperty(« value », 0.0)
        self.lcdNumberDelaiMesure.setObjectName(_fromUtf8(« lcdNumberDelaiMesure »))
        self.pushButtonEffacer = QtGui.QPushButton(Form)
        self.pushButtonEffacer.setGeometry(QtCore.QRect(575, 195, 66, 27))
        self.pushButtonEffacer.setObjectName(_fromUtf8(« pushButtonEffacer »))

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

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate(« Form », « PyQt + pyqtgraph : Affichage courbe progressive avec stop, lcdNumber », None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditValeurMin.setText(QtGui.QApplication.translate(« Form », « -1000 », None, QtGui.QApplication.UnicodeUTF8))
        self.labelUnite.setText(QtGui.QApplication.translate(« Form », « Unité : », None, QtGui.QApplication.UnicodeUTF8))
        self.labelValeurCalc.setText(QtGui.QApplication.translate(« Form », « Valeur calculée : », None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditValeurMax.setText(QtGui.QApplication.translate(« Form », « +1000 », None, QtGui.QApplication.UnicodeUTF8))
        self.labelDelaiMesure.setText(QtGui.QApplication.translate(« Form », « delai ms », None, QtGui.QApplication.UnicodeUTF8))
        self.labelValeurBrute.setText(QtGui.QApplication.translate(« Form », « Valeur brute : », None, QtGui.QApplication.UnicodeUTF8))
        self.labelValeurMin.setText(QtGui.QApplication.translate(« Form », « Valeur mini », None, QtGui.QApplication.UnicodeUTF8))
        self.pushRadioButtonStop.setText(QtGui.QApplication.translate(« Form », « STOP », None, QtGui.QApplication.UnicodeUTF8))
        self.labelValeurMax.setText(QtGui.QApplication.translate(« Form », « Valeur maxi », None, QtGui.QApplication.UnicodeUTF8))
        self.lineEditUnite.setText(QtGui.QApplication.translate(« Form », « U », None, QtGui.QApplication.UnicodeUTF8))
        self.pushButtonEffacer.setText(QtGui.QApplication.translate(« Form », « Effacer », None, QtGui.QApplication.UnicodeUTF8))

from pyqtgraph import PlotWidget

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 – Mai 2013 – Tous droits réservés
# GPLv3 – www.mon-club-elec.fr

# modules a importer
from PyQt4.QtGui import *
from PyQt4.QtCore import *  # inclut QTimer..
import os,sys

import pyqtgraph as pg # pour accès à certaines constantes pyqtgraph, widget, etc…

import numpy as np # math et tableaux

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

# +/- variables et objets globaux

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

                # — Variables de classe
                # — Paramétrage des widgets de l’interface GUI si nécessaire —

                # — Connexions entre signaux des widgets et fonctions
                # connecte chaque signal utilisé des objets à l’appel de la fonction voulue

                self.connect(self.pushButtonEffacer, SIGNAL(« clicked() »), self.pushButtonEffacerClicked) # connecte le signal Clicked de l’objet bouton à l’appel de la fonction voulue

                self.connect(self.pushRadioButtonStop, SIGNAL(« clicked() »), self.pushRadioButtonStopClicked) # connecte le signal Clicked de l’objet bouton à l’appel de la fonction voulue

                self.connect(self.dialDelaiMesure, SIGNAL(« valueChanged(int) »), self.dialDelaiMesureChanged) # connecte le signal Clicked de l’objet bouton à l’appel de la fonction voulue

                self.pushRadioButtonStop.setStyleSheet(QString.fromUtf8(« background-color: rgb(0, 255, 0); »)) # bouton de stop en vert au depart

                #– pour délais de mesure en ms
                self.delaisMesure=[1,2,4,8,16,32,64,128,256] # en ms
                self.interval=self.delaisMesure[4] # intervalle entre  2 valeurs – en ms
                self.lcdNumberDelaiMesure.display(self.delaisMesure[4]) # valeur initiale pour le délai

                # — Code actif initial  —

                #– initialise le graphique pyqtgraph —
                # l’objet self.graph correspond au plotWidget créé dans QtDesigner

                # aspect fond /axes
                #self.graph.hideAxis(‘left’) # masque axes – ‘left’, ‘bottom’, ‘right’, or ‘top’               
                self.graph.setBackgroundBrush(QBrush(QColor(Qt.white))) # la classe PlotWidget est un GraphicsWidget qui est un QGraphics View
                self.graph.showGrid(x=True, y=True)  # affiche la grille
                self.graph.getAxis(‘bottom’).setPen(pg.mkPen(0,0,255)) # couleur de l’axe + grille
                self.graph.getAxis(‘left’).setPen(pg.mkPen(255,0,0)) # couleur de l’axe + grille

                # légende des axes
                labelStyle = {‘color’: ‘#00F’, ‘font-size’: ’10pt’} # propriétés CSS à utiliser pour le label
                self.graph.getAxis(‘bottom’).setLabel(‘X’, units=‘unit’, **labelStyle) # label de l’axe
                self.graph.getAxis(‘left’).setLabel(‘Y’, units=‘unit’, **labelStyle) # label de l’axe

                # adaptation échelle axes
                # axe X et Y sont autoscale par défaut
                self.graph.enableAutoRange(axis=pg.ViewBox.YAxis, enable=False) # fonction plotItem : désactive autoscale Y

                self.Ymin=-1
                self.Ymax=1            
                self.graph.setYRange(self.Ymin,self.Ymax) # fonction plotItem : fixe échelle des Y

                self.Xmin=0
                self.Xmax=360  
                self.graph.setXRange(self.Xmin,self.Xmax) # fonction plotItem : fixe échelle des X

                # interactivité
                #self.graph.setInteractive(False) # fonction QGraphics View : pour inactiver interaction souris
                self.graph.getViewBox().setMouseMode(pg.ViewBox.RectMode)  # fonction ViewBox pas accessible depuis PlotWidget : fixe selection par zone
                self.graph.setMouseEnabled(x=False, y=True) # désactive interactivité axe X

                #– initialise données —
                #– définition des x
                #self.nombreValeurs=360
                #self.x = np.arange(0.0, self.nombreValeurs+1, 1.0) # crée un vecteur de n valeurs à intervalle régulier pour les x
                #print(self.x) # debug – affiche les valeurs x

                #– calcul des y : courbe y=f(x)
                #self.y=np.sin(np.radians(self.x))# crée un tableau de valeur y basé sur x – courbe y=sin(x)
                #self.y= np.random.normal(0,1,size=self.nombreValeurs) # génére une série de 1000 valeurs aléatoires

                #print(self.y) # debug – affiche les valeurs y

                #– affichage de la courbe —
                self.courbe=self.graph.plot(pen=(0,0,255)) # avec couleur

                self.compt=0 # variable comptage

                #– initialisation du Timer
                self.timer=QTimer() # déclare un timer Qt
                self.timer.start(self.interval) # lance le timer – durée en ms
                self.connect(self.timer, SIGNAL(« timeout() »), self.timerEvent) # connecte le signal timeOut de l’objet timer à l’appel de la fonction voulue
                # NB : le nom de la fonction appelée est ici timerEvent : ce nom est arbitraire et peut être ce que l’on veut…

        # — les fonctions appelées, utilisées par les signaux des widgets —

        #— si modif delai mesure —
        def dialDelaiMesureChanged(self, valeur):
                print(« Dial Delai Mesure modifié : «  + str(valeur) +  » | délai = «  + str(self.delaisMesure[valeur]) +  » ms »)
                self.lcdNumberDelaiMesure.display(self.delaisMesure[valeur]) # utilise la valeur [i] pour le délai

                self.interval=self.delaisMesure[valeur]
                self.timer.setInterval(self.interval) # modifie le nouvel intervalle du timer

                if self.pushRadioButtonStop.isChecked()is not True: # si le bouton stop est pas enfoncé
                        self.timer.start() # redémarre le timer

        #—- bouton STOP ——-
        def pushRadioButtonStopClicked(self):
                print(« Bouton Stop appuyé »)
                print(« Etat bouton Stop = » + str(self.pushRadioButtonStop.isChecked()))
                if self.pushRadioButtonStop.isChecked(): # si bouton enfoncé
                        self.pushRadioButtonStop.setStyleSheet(QString.fromUtf8(« background-color: rgb(255, 0, 0); »))
                        self.timer.stop() # stop le timer
                else:
                        self.pushRadioButtonStop.setStyleSheet(QString.fromUtf8(« background-color: rgb(0, 255, 0); »))
                        self.timer.start() # redémarre le timer

        #— bouton effacer —
        def pushButtonEffacerClicked(self):
                print(« Bouton Effacer cliqué »)
                #self.timer.stop() # arret timer
                self.compt=0 # réinitialise comptage valeurs et donc graphique…
                self.timerEvent() # appelle la fonction timerEvent pour prise en compte immédiate

        # — les fonctions appelées, utilisées par les signaux hors widgets —

        #– fonction gestion survenue évènement Timer
        def timerEvent(self): # fonction appelée lors de la survenue d’un évènement Timer – nom de la fonction indiférrent
                #print(« Timer »)

                if self.compt==0: # premier passage
                        self.points= np.array([[self.compt,self.compt]]) # tableau à 2 dimensions – ici 1er points
                        newY=np.sin(np.radians(self.compt)) * np.cos(np.radians(3*self.compt))
                        self.x=self.points[:,0] # la première colonne = les x
                        self.y=self.points[:,1] # la deuxième colonne = les y          
                        self.compt=self.compt+1 # incrémente compt
                elif self.compt<=self.Xmax: # on remplit le tableau de point une première fois
                        newY=np.sin(np.radians(self.compt)) * np.cos(np.radians(3*self.compt))
                        #newY=self.compt # x=y – debug
                        self.points=np.append(self.points,[[self.compt,newY]],axis=0)# ajouter un point au tableau
                        self.x=self.points[:,0] # la première colonne = les x
                        self.y=self.points[:,1] # la deuxième colonne = les y          
                        self.compt=self.compt+1 # incrémente compt
                else:
                        #self.points=roll(self.points,1, axis=1) # décale les éléments y de 1 – fonctin numpy
                        #self.x=self.points[:,0] # la première colonne = les x – existe déjà
                        #self.y=self.points[:,1] # la deuxième colonne = les y – existe déjà

                        #self.y=roll(self.y,1) # décale les éléments y de 1 – fonctin numpy – les x ne bougent pas..
                        self.y=np.roll(self.y,-1) # décale les éléments y de 1 – fonction numpy – les x ne bougent pas.. et remet y[0] en y[max].. évite recalcul…
                        newY=self.y[len(self.y)1] # derniere valeur du tableau y
                        #self.y[self.Xmax-1]=self.y[self.Xmax-1]/2 # nouvelle valeur en dernière position
                        #self.y[self.Xmax]=0 # nouvelle valeur en dernière position
                        #self.y[self.Xmax]=np.sin(np.radians(self.compt)) * np.cos(np.radians(3*self.compt)) # avec recalcul
                        #self.compt=self.compt+1 # incrémente compt

                        # important : pour le tracé, ce n’est pas l’ordre qui est important, mais la coordonnée x,y dans notre cas…

                # remarquer la simplicité avec laquelle il es possible d’extraire le tableau des x ou des y à partir du tableau de points

                #if self.compt==self.Xmax : self.compt=0 # RAZ compt

                # debug
                #print self.points
                #print self.x  
                #print self.y

                «  » »
                #– initialise données —
                self.x = arange(0.0, 361.0, 1.0) # crée un vecteur de n valeurs à intervalle régulier pour les x
                print(self.x) # debug – affiche les valeurs x

                #self.y = zeros(len(self.x), Float) # debug – crée un tableau rempli de 0 de la taille voulue pour les y       
                #– calcul des y : courbe y=sin(x).cos(3x)
                self.y=sin(radians(self.x)) * cos(radians(3*self.x))# crée un tableau de valeur y basé sur x
                print(self.y) # debug – affiche les valeurs y
                «  » »
                #– met à jour leslcdNumber
                # actualise lcdNumber
                self.lcdNumberValeurBrute.display(newY) # affiche la valeur

                # équiv map : interp(256,[1,512],[5,10]) (package numpy)
                self.valeurCalc=np.interp(newY, [1,1],[float(self.lineEditValeurMin.text()),float(self.lineEditValeurMax.text())]) # équiv map
                self.lcdNumberValeurCalc.display(self.valeurCalc)

                #– initialise la courbe —
                self.courbe.setData(self.x,self.y) # initialisation valeurs courbe

        # — fonctions de classes autres—    

# — Autres Classes utiles —

# — Classe principale (lancement)  —
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
  • Le bouton de Stop arrêt de défilement, le bouton effacer, efface, le bouton rotatif assure le réglage de la vitesse de défilement.

Discussion technique

  • Il serait préférable de ne pas actualiser le graphique à la même fréquence que le calcul de valeur : si délai à 2ms, cela fait 500 calculs par seconde, et 500 rafraîchissement. On peut imaginer plutôt de rafraîchir que toutes les 33 ms (=30 fps) tout en faisant calcul à 500 / s
Noter cet article

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Archive Mon Club Elec

Articles populaires

Newsletter

Inscrivez-vous maintenant et bénéficiez d'un soutien continu pour réaliser vos travaux électriques en toute sécurité.