View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

PYQTLAB

PyQt Lab' : Graphiques Math : Pyqtgraph : Afficher/masquer des courbes dans un graphique Pyqtgraph à l'aide widgets checkbox.

Par X. HINAULT - Mai 2013

Ce que l'on va faire ici

  • Plusieurs "cases à cocher" (checkbox) permettent de sélectionner les courbes à masquer / afficher parmi plusieurs dans un graphique pyqtgraph.

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>542</width>
    <height>457</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>PyQt + pyqtgraph : Affichage de courbes multiples sélectionnables</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="QCheckBox" name="checkBoxCourbe1">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>380</y>
     <width>136</width>
     <height>19</height>
    </rect>
   </property>
   <property name="text">
    <string>Courbe y=sin(x)</string>
   </property>
  </widget>
  <widget class="QCheckBox" name="checkBoxCourbe2">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>400</y>
     <width>136</width>
     <height>19</height>
    </rect>
   </property>
   <property name="text">
    <string>Courbe y=cos(2x)</string>
   </property>
  </widget>
  <widget class="QCheckBox" name="checkBoxCourbe3">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>420</y>
     <width>246</width>
     <height>19</height>
    </rect>
   </property>
   <property name="text">
    <string>Courbe y= série de valeurs aléatoires</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 '/home/xavier/www/mon_arduino/python_avec_arduino/mes_pyQt_tutos_v2/pyqtgraph/tuto_pyqt_pyqtgraph_courbe_multiple_checkbox/codes/tuto_pyqt_pyqtgraph_courbe_multiple_checkbox.ui'
#
# Created: Sun Jun  2 19:00:16 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(542, 457)
        self.graph = PlotWidget(Form)
        self.graph.setGeometry(QtCore.QRect(5, 10, 480, 360))
        self.graph.setObjectName(_fromUtf8("graph"))
        self.checkBoxCourbe1 = QtGui.QCheckBox(Form)
        self.checkBoxCourbe1.setGeometry(QtCore.QRect(10, 380, 136, 19))
        self.checkBoxCourbe1.setObjectName(_fromUtf8("checkBoxCourbe1"))
        self.checkBoxCourbe2 = QtGui.QCheckBox(Form)
        self.checkBoxCourbe2.setGeometry(QtCore.QRect(10, 400, 136, 19))
        self.checkBoxCourbe2.setObjectName(_fromUtf8("checkBoxCourbe2"))
        self.checkBoxCourbe3 = QtGui.QCheckBox(Form)
        self.checkBoxCourbe3.setGeometry(QtCore.QRect(10, 420, 246, 19))
        self.checkBoxCourbe3.setObjectName(_fromUtf8("checkBoxCourbe3"))

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

    def retranslateUi(self, Form):
        Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQt + pyqtgraph : Affichage de courbes multiples sélectionnables", None, QtGui.QApplication.UnicodeUTF8))
        self.checkBoxCourbe1.setText(QtGui.QApplication.translate("Form", "Courbe y=sin(x)", None, QtGui.QApplication.UnicodeUTF8))
        self.checkBoxCourbe2.setText(QtGui.QApplication.translate("Form", "Courbe y=cos(2x)", None, QtGui.QApplication.UnicodeUTF8))
        self.checkBoxCourbe3.setText(QtGui.QApplication.translate("Form", "Courbe y= série de valeurs aléatoires", 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_courbe_multiple_checkbox 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.checkBoxCourbe1, SIGNAL("clicked()"), self.checkBoxCourbe1Clicked) # connecte le signal Clicked de l'objet checkBox à l'appel de la fonction voulue
                self.connect(self.checkBoxCourbe2, SIGNAL("clicked()"), self.checkBoxCourbe2Clicked)
                self.connect(self.checkBoxCourbe3, SIGNAL("clicked()"), self.checkBoxCourbe3Clicked)

                # --- 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.minY=-1
                self.maxY=1            
                self.graph.setYRange(self.minY,self.maxY) # fonction plotItem : fixe échelle des Y

                # 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 --
                self.nombreValeurs=360 # paramètre commun

                #-- définition des x - ici commun - mais on peut utiliser des x différents si on veut
                self.x = np.arange(0.0, self.nombreValeurs, 1.0) # crée un vecteur de n valeurs à intervalle régulier pour les x
                print(self.x) # debug - affiche les valeurs x

                # courbe 1 :

                #-- calcul des y : courbe y=f(x)
                self.y1=np.sin(np.radians(self.x))# crée un tableau de valeur y basé sur x - courbe y=sin(x)

                print(self.y1) # debug - affiche les valeurs y

                #-- affichage de la courbe --
                self.courbe1=self.graph.plot(self.x,self.y1, pen=(0,0,255)) # avec couleur
                self.checkBoxCourbe1.setChecked(True) # sélectionne le checkbox

                # courbe 2 :
                #-- calcul des y : courbe y=f(x)
                self.y2=np.cos(np.radians(2*self.x))# crée un tableau de valeur y basé sur x - courbe y=cos(2.x)

                print(self.y2) # debug - affiche les valeurs y

                #-- affichage de la courbe --
                self.courbe2=self.graph.plot(self.x,self.y2, pen=(255,0,255)) # avec couleur
                self.checkBoxCourbe2.setChecked(True) # sélectionne le checkbox

                # courbe 3 :
                #-- calcul des y : liste de valeurs aléatoires
                self.y3= 0.3*np.random.normal(0,1,size=self.nombreValeurs) # génére une série de 1000 valeurs aléatoires

                print(self.y3) # debug - affiche les valeurs y

                #-- affichage de la courbe --
                self.courbe3=self.graph.plot(self.x,self.y3, pen=(0,127,255)) # avec couleur
                self.checkBoxCourbe3.setChecked(True) # sélectionne le checkbox

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

        #-- courbe 1
        def checkBoxCourbe1Clicked(self):
                print("Checkbox cliqué")

                if self.checkBoxCourbe1.isChecked(): # si checkBox sélectionné
                        print("Etat checkBox = " + str(self.checkBoxCourbe1.isChecked())) # affiche l'état de la ckeckBox
                        self.courbe1=self.graph.plot(self.x,self.y1, pen=(0,0,255)) # dessine la courbe

                else : # si checkBox pas sélectionné
                        print("Etat checkBox = " + str(self.checkBoxCourbe1.isChecked()))
                        self.graph.removeItem(self.courbe1)

        #-- courbe 2
        def checkBoxCourbe2Clicked(self):
                print("Checkbox cliqué")

                if self.checkBoxCourbe2.isChecked(): # si checkBox sélectionné
                        print("Etat checkBox = " + str(self.checkBoxCourbe2.isChecked())) # affiche l'état de la ckeckBox
                        self.courbe2=self.graph.plot(self.x,self.y2, pen=(255,0,255)) # dessine la courbe

                else : # si checkBox pas sélectionné
                        print("Etat checkBox = " + str(self.checkBoxCourbe2.isChecked()))
                        self.graph.removeItem(self.courbe2)

        #-- courbe 3
        def checkBoxCourbe3Clicked(self):
                print("Checkbox cliqué")

                if self.checkBoxCourbe3.isChecked(): # si checkBox sélectionné
                        print("Etat checkBox = " + str(self.checkBoxCourbe3.isChecked())) # affiche l'état de la ckeckBox
                        self.courbe3=self.graph.plot(self.x,self.y3, pen=(0,127,255)) # dessine la courbe

                else : # si checkBox pas sélectionné
                        print("Etat checkBox = " + str(self.checkBoxCourbe3.isChecked()))
                        self.graph.removeItem(self.courbe3)

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

        # --- 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
  • La molette de souris assure le zoom
  • Cliquer les cases à cocher pour masquer/afficher les courbes.