Cours-Gratuit
  • Cours
  • Blog
home icon Cours gratuits » Cours informatique » Cours programmation » Cours Python » Cours Framework Python

Introduction à la programmation graphique avec Python et Kivy

Introduction à la programmation graphique avec Python et Kivy
Participez au vote ☆☆☆☆☆★★★★★
Aller au Téléchargement

                                                                  PI2T Développement informatique

Séance 8

Programmation graphique

Sébastien Combéfis, Quentin Lurkin                                               17 mars 2016

Ce(tte) œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution – Pas d’Utilisation Commerciale – Pas de Modification 4.0 International.

Objectifs

Programmation graphique et évènementielle

Utilisation de la librairie Kivy

Application graphique et widgets

Programmation de jeu

Dessin avec les canvas

Gestion des collisions


Librairie Kivy

 Framework open-source pour créer des interfaces utilisateur Application desktop ou mobile, jeux

Plusieurs avantages offerts par la librairie

Multi-plateforme (Linux, Windows, OS X, Android, iOS)

Framework stable, API documentée

Moteur graphique basé sur OpenGL ES 2 (utilisation du GPU)

Kivy est disponible sur GitHub


Hello World (1)

 Interface représentée par une classe de type App

Définition des composants dans la méthode build

Liaison d’un gestionnaire d’évènement avec bind

fromimport App from .button import Button, Label from .boxlayout import BoxLayout

class HelloApp(App):

def build(self):

box = BoxLayout(orientation=’vertical’) box.add_widget(Label(text=’Hello World!’)) quitbtn = Button(text=’Quitter’) (on_press=self._quit) box.add_widget(quitbtn) return box

def _quit(self, instance):

App.get_running_app().stop()

if __name__ == ’__main__’:

HelloApp().run()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Hello World (2)

 Interface graphique découpée en deux parties verticalement

Label en haut et bouton en bas

Application minimale

 Créer le programme dans un fichier

Convention utile pour builder les versions mobiles

Objet de type App initialise une série de choses avec run interaction avec le hardware de l’écran

discuter avec des dispositifs d’entrée comme écran multitouch, clavier, accéléromètre planification de plusieurs tâches

fromimport App

App().run()

1

2

3

Application graphique

 Code d’une application graphique placé dans une classe

La classe doit être de type App

Lancement de l’application par la méthode run

Possibilité de décrire l’interface avec le langage KV

Langage balisé de description d’interfaces graphiques

fromimport App

class MetroApp(App):

pass

if __name__ == ’__main__’:

MetroApp().run()

1

2

3

4

5

6

7

Langage KV

 Fichier .kv qui porte le même nom que l’application

Donc dans notre exemple

 Liste des composants avec leurs propriétés Label, champ texte, layout, onglets

#:kivy 1.0 #

# author: Sébastien Combéfis

# version: March 16, 2016

Label:

text: "Hello World"

1

2

3

4

5

6

7

Widget

 Boite avec un comportement et pouvant contenir des boites

La classe Widget représente une boite vide

Exemples de widgets

Un Label permet d’afficher un texte

Un Button permet de répondre à un toucher ou click

Un TextInput réagit aux évènements clavier

Un widget complexe peut être construit à partir d’autres

TabbedPanel, FileChooser

Hiérarchie de widgets

 Déclaration d’un widget racine par fichier KV

Il s’agit simplement de celui déclaré le plus à l’extérieur

Chaque déclaration possède un bloc specifier

Définition de propriétés du widget

Définition de widgets fils

Le widget racine est directement attaché à la fenêtre

Application Métro (1)

 Fenêtre avec deux zones : contrôle en haut et affichage en bas Les tabulations définissent la hiérarchie des widgets

BoxLayout: orientation: ’vertical’ BoxLayout:

orientation: ’horizontal’ size_hint: (1,.2) Label: text: ’Line’ TextInput: multiline: False Label: text: ’Station’ TextInput: multiline: False Button: text: ’Charger’ Label:

text: "Entrez le numéro de la ligne et de l’arrêt qui vous intéresse." size_hint: (1,.8)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Application Métro (2)

 Taille de départ de la fenêtre déterminée par configuration

from kivy.config import Config Config.set(’graphics’, ’width’, 800) Config.set(’graphics’, ’height’, 300)

1

2

3

Évènement

 Un évènement est quelque chose qui se produit

Kivy produit pleins d’évènements divers et variés, en permanence

Boucle d’évènements lancée par la méthode run

Parcours permanent des sources d’évènements

Relais des évènements vers le code de l’application

Plusieurs types d’évènements

Clic, déplacement de souris, clavier, timer, accéléromètre

Gestionnaire d’évènements

 Un gestionnaire d’évènement répond à leurs occurrences

Représenté par une fonction ou méthode

Le gestionnaire reçoit des informations sur l’évènement

Source de l’évènement

Informations diverses selon le type d’évènement

class MetroApp(App):

def loadschedule(self): print(’coucou’)

1

2

3

Binding

 Attache d’un gestionnaire pour un évènement sur widget cible

Utilisation d’une propriété dans le fichier KV

 Propriété spécifique par type d’évènement

Par exemple, on_press pour un clic

#:import App

BoxLayout: orientation: ’vertical’ BoxLayout:

#

Button:

text: ’Charger’

on_press: App.get_running_app().loadschedule() Label:

text: "Entrez le numéro de la ligne et de l’arrêt qui vous intéresse." size_hint: (1,.8)

1

2

3

4

5

6

7

8

9

10

11

12

Créer son propre widget

 Création d’un nouveau widget en créant une nouvelle classe

Le type de la classe est typiquement un widget layout

 Comportement déplacé et modification du fichier KV

class MetroForm(BoxLayout):

def loadschedule(self):

print(’coucou’)

class MetroApp(App):

pass

1

2

3

4

5

6

MetroForm: orientation: ’vertical’ BoxLayout:

#

Button:

text: ’Charger’ on_press: root.loadschedule() #

1

2

3

4

5

6

7

8

Propriété (1)

 Lien entre le fichier KV et le code Python avec des propriétés

Objet ObjectProperty représente les propriétés dans le widget

 Permet un accès direct au widget et à ses méthodes

Accessibles comme variables d’instance avec self

class MetroForm(BoxLayout):

line_input = ObjectProperty() station_input = ObjectProperty()

def loadschedule(self):

print() print()

1

2

3

4

5

6

7

Propriété (2)

 Ajout d’un identifiant unique pour les widgets avec id

Uniquement accessible à l’intérieur du fichier KV

 Lien entre les propriétés et les identifiants

MetroForm:

orientation: ’vertical’ line_input: line station_input: station BoxLayout:

#

TextInput:

id: line multiline: False #

TextInput:

id: station multiline: False #

#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Application Métro (3)

 Récupération des horaires des prochains métro avec API STIB

class MetroForm(BoxLayout):

line_input = ObjectProperty() station_input = ObjectProperty() result_output = ObjectProperty()

def loadschedule(self):

url = ’?line={}&halt={}’.

format(, ) with urllib.request.urlopen(url) as response:

= ().decode()

1

2

3

4

5

6

7

8

9

Application Métro (4)

 Réponse fournie par l’API au format XML

<waitingtimes>

<stopname>ALMA</stopname> <position>

<latitude>50.85</latitude>

<longitude>4.453</longitude>

</position>

<message mode="1">

DU 17/3 A 12H AU 18/3 A 14H, SOMMET EUROPEEN. STATION SCHUMAN FERMEE. CORRESPONDANCE BUS A MAELBEEK.

</message>

<waitingtime>

<line>1</line>

<mode>M</mode>

<minutes>1</minutes>

<destination>GARE DE L’OUEST</destination> <message/>

</waitingtime> <waitingtime>

<line>1</line>

<mode>M</mode>

<minutes>6</minutes>

<destination>GARE DE L’OUEST</destination>

<message/>

</waitingtime>

</waitingtimes>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Application Métro (5)

 Extraction des données du XML par expression régulière

Récupération de la direction du métro et du temps d’attente

with urllib.request.urlopen(url) as response:

xml = ().decode() pattern = r"<waitingtime>.*?<minutes>([0-9]+)</minutes>.*?< destination>([A-Z ’]+)</destination>.*?</waitingtime>" p = re.compile(pattern) schedule = ’’ for m in p.finditer(xml): schedule += ’Vers {} : prochain dans {} minutes\n’.format(m

.group(2), m.group(1)) = schedule

1

2

3

4

5

6

7

8

Bonne pratique

 Séparation recommandée entre présentation et logique

Avoir un fichier KV et un fichier Python

 Layout de la fenêtre et insertion des composants en KV

En définissant des id et des propriétés

 Aspects logiques et gestionnaire d’évènements dans le Python

Lien avec les composants grâce aux propriétés



Dessin

 Capacité de dessin sophistiquée (statique ou animé)

Exploitation des capacités de OpenGL et SDL

 OpenGL est une API de calcul d’images 2D ou 3D

Géométrie d’objets et calcul de projection à l’écran

 SDL est une bibliothèque utilisée pour créer des jeux 2D

Affichage vidéo, audio numérique, périphériques (clavier, souris)

Canvas (1)

 Utilisation du canvas d’un widget comme zone de dessin

Zone de dessin vierge obtenue avec des widgets de type layout

 Séquence d’opérations graphiques à réaliser dans le canvas Dessin de ligne, ellipse, rectangle; choix de la couleur

TurningSquareForm:

canvas:

Color: rgb: [0.7, 0.2, 0] Rectangle:

pos: (50, 50) size: (100, 50)

1

2

3

4

5

6

7

Canvas (2)

 Création de l’application graphique par défaut

Deux classes vides (application et widget personnalisé)

class TurningSquareForm(BoxLayout):

pass

class TurningSquareApp(App):

pass

if __name__ == ’__main__’:

TurningSquareApp().run()

1

2

3

4

5

6

7

8

Transformation (1)

 Trois transformations possibles sur les objets dessinés

Rotation, translation et mise à l’échelle

TurningSquareForm:

canvas:

Color: rgb: [0.7, 0.2, 0] Rectangle:

pos: (50, 50) size: (100, 50) Color: rgb: [0, 0.2, 0.7] Rotate:

origin: (150, 50) angle: -135 axis: (0, 0, 1)

Scale: origin: (150, 50) x: 0.5 y: 0.5 Rectangle:

pos: (50, 50) size: (100, 50)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

Transformation (2)

 L’ordre d’application des transformations est important Tout comme certains paramètres comme l’origine ou l’axe

Composant déplaçable

Définition d’un nouveau composant qui est déplaçable

Le composant DraggableWidget est générique

Le composant DraggableRectangle est un cas particulier

MovableRectanglesForm:

DraggableRectangle:

DraggableRectangle: size: (50, 50) color: [0, 0.2, 0.7]

<DraggableWidget>: size_hint: (None, None)

<DraggableRectangle>: size: (100, 100) color: [0.7, 0.2, 0] canvas:

Color: rgb: self.color Rectangle:

pos: (10, 10) size: ([0] - 20, [1] - 20)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Application MovableRectangles

 Définition d’un widget générique déplaçable

Gestionnaires pour les évènements touch (down, move et up)

class DraggableWidget(RelativeLayout):

def __init__(self, **kwargs):

self.__selected = None super(DraggableWidget, self).__init__(**kwargs) #

class DraggableRectangle(DraggableWidget):

pass

class MovableRectanglesForm(BoxLayout):

pass

class MovableRectanglesApp(App):

pass

if __name__ == ’__main__’:

MovableRectanglesApp().run()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Touch down

 Test de collision entre coordonnée de touch et rectangle collide_pointstest si un point est dans soi-même

Deux situations possibles

Si collision, marquer le rectangle comme sélectionné

Sinon, comportement par défaut

def on_touch_down(self, touch):

if self.collide_point(touch.x, touch.y):

self.select() return True

return super(DraggableWidget, self).on_touch_down(touch)

1

2

3

4

5

Touch up

 Déselection du rectangle actuellement sélectionné si existant Et suppression du dessin de sélection de l’écran

def on_touch_up(self, touch):

if self.__selected:

self.unselect() return True

return super(DraggableWidget, self).on_touch_up(touch)

1

2

3

4

5

Touch move

 Translation du rectangle vers la nouvelle position

Si cette dernière se trouve dans les limites du parent

def on_touch_move(self, touch):

(x, y) = self.parent.to_parent(touch.x, touch.y) if self.__selected and self.parent.collide_point(x - self.width / 2, y - self.height / 2):

self.translate(touch.x - self.__ix, touch.y - self.__iy) return True

return super(DraggableWidget, self).on_touch_move(touch)

1

2

3

4

5

6

Sélection/Désélection

 Sélection d’un objet lors d’un touch down

Dessin d’un rectangle pointillé autour de l’objet

 Désélection d’un objet lors d’un touch up

Suppression du rectangle pointillé

def select(self):

if not self.__selected:

self.__ix = self.center_x self.__iy = self.center_y with self.canvas:

self.__selected = Line(rectangle=(0, 0, self.width, self.height), dash_offset=2)

def unselect(self):

if self.__selected:

self.canvas.remove(self.__selected) self.__selected = None

1

2

3

4

5

6

7

8

9

10

11

Translation

 Translation de l’objet sélectionné

Calcul de la nouvelle position avec le shift de touch move

def translate(self, x, y):

self.center_x = self.__ix = self.__ix + x self.center_y = self.__iy = self.__iy + y

1

2

3

Livres de référence

       ISBN                                        ISBN

       978-1-491-94667-1                   978-1-785-28692-6

Crédits

Photos des livres depuis Amazon

Articles similaires

  • Tutoriel Python : Notions de base
  • Tuto Python & Tkinter : programmation événementielle
  • Tutoriel Excel : comment faire un graphique radar
  • Comment coder pour les débutants
  • Tutoriel Excel : créer un graphique circulaire avec des pourcentages
  • Tutoriel python: réaliser des graphiques avec pyplot

Documents similaires

  • Tutoriel pour débuter avec le Framework Python Kivy

    Tutoriel pour débuter avec le Framework Python Kivy

  • Cours de programmation python et interface graphique

    Cours de programmation python et interface graphique

  • Cours sur les interfaces graphiques en Python avec PyQt

    Cours sur les interfaces graphiques en Python avec PyQt

  • Introduction à l’algorithmique et à la programmation avec Python

    Introduction à l’algorithmique et à la programmation avec Python

  • Python livre pour debuter la programmation avec le language

    Python livre pour debuter la programmation avec le language

  • Initiation à la programmation avec Python et C++

    Initiation à la programmation avec Python et C++

  • Contactez-nous
  • A propos de nous
  • On recrute
  • Rechercher dans le site
  • Politique de confidentialité
  • Droit d'auteur/Copyright
  • Conditions générales d'utilisation
  • Plan du site
  • Accueil
  • Blog
  • Finance et compta.
  • Formations Pro.
  • Logiciels & Apps
  • Organisation
  • Cours informatique
  • Aide à la rédaction
  • Etudes et Metiers
  • Cours commerce
  • Cours électricité
  • Cours finance
  • Cours statistique
  • Cours économie
  • Cours Management
  • Cours comptabilité
  • Cours électronique
  • Cours gestion
  • Cours marketing
id 11354 02