Académique Documents
Professionnel Documents
Culture Documents
com
Documentation Kivy
Version 2.1.0.dev0
08 octobre 2021
CONTENU
je Projet Kivy 3
1 Philosophie 5
2 Contribuant sept
3 FAQ 23
4 Nous contacter 29
II Guide de programmation 31
5 Les bases de Kivy 33
6 Contrôler l'environnement 39
sept
Configurer Kivy 43
8 Aperçu architectural 45
9 Événements et propriétés 49
11 widgets 67
12 graphiques 87
Langue 13Kv 89
je
IV Référence de l'API 155
Cadre 20 Kivy 157
23 effets 303
24 Jardin 309
25 graphiques 313
29 modules 441
31 Stockage 457
32 outils 463
33 widgets 465
V Annexe 715
34 Permis 717
Indice 721
je
Bienvenue dans la documentation de Kivy. Kivy est une bibliothèque de logiciels open source pour le développement rapide
d'applications équipées de nouvelles interfaces utilisateur, telles que les applications multi-touch.
Nous vous recommandons de commencer par Commencer. Dirigez-vous ensuite vers leGuide de programmation. Nous avons
égalementCréer une candidature si vous êtes impatient.
Vous vous demandez probablement pourquoi vous devriez être intéressé par l'utilisation de Kivy. Il existe un document
décrivant notrePhilosophie que nous vous encourageons à lire, et un Aperçu architectural.
Si vous souhaitez contribuer à Kivy, assurez-vous de lire Contribuant. Si votre problème n'est pas traité dans la
documentation, n'hésitez pas àNous contacter.
1
2
Partie I
PROJET KIVY
Cette partie de la documentation explique les idées de base derrière la conception de Kivy et pourquoi vous voudriez l'utiliser.
3
4
CHAPITRE
UN
PHILOSOPHIE
Si vous vous demandez en quoi consiste Kivy et ce qui le distingue des autres solutions, ce document
est pour vous.
Pourquoi voudriez-vous utiliser Kivy? Après tout, il existe de nombreuses boîtes à outils (ou frameworks, ou plates-
formes) intéressantes - gratuitement. Vous avez Qt et Flash, pour ne citer que deux bons choix pour le développement
d'applications. Beaucoup de ces nombreuses solutions prennent déjà en charge Multi-Touch, alors qu'est-ce qui rend
Kivy spécial et intéressant à utiliser ?
1.1.1 Frais
Kivy est fait pour aujourd'hui et pour demain. Les nouvelles méthodes de saisie telles que Multi-Touch sont devenues de plus en
plus importantes. Nous avons créé Kivy à partir de zéro, spécifiquement pour ce type d'interaction. Cela signifie que nous avons
pu repenser beaucoup de choses en termes d'interaction homme-machine, alors que les boîtes à outils plus anciennes (pour ne
pas dire « obsolètes », plutôt « bien établies ») portent leur héritage, qui est souvent un fardeau. Nous n'essayons pas de forcer
cette nouvelle approche de l'utilisation d'un ordinateur dans le corset des modèles existants (disons l'interaction d'un seul
pointeur avec la souris). Nous voulons le laisser s'épanouir et vous laisser explorer les possibilités.Cette est ce qui distingue
vraiment Kivy.
1.1.2 Rapide
Kivy est rapide. Ceci s'applique aux deuxdéveloppement d'applications et exécution de l'application vitesses. Nous avons
optimisé Kivy de plusieurs manières. Nous implémentons des fonctionnalités urgentes sur leniveau C pour tirer parti de la
puissance des compilateurs existants. Plus important encore, nous utilisons égalementalgorithmes intelligents pour minimiser
les opérations coûteuses. Nous utilisons également leGPU partout où cela a du sens dans notre contexte. La puissance de calcul
des cartes graphiques d'aujourd'hui dépasse de loin celle des processeurs d'aujourd'hui pour certaines tâches et algorithmes,
en particulier le dessin. C'est pourquoi nous essayons de laisser le GPU faire le plus de travail possible, augmentant ainsi
considérablement les performances.
5
1.1.3 Souple
Kivy est flexible. Cela signifie qu'il peut être exécuté surune variété d'appareils différents, y compris les smartphones et tablettes
Android. Nous soutenonstous les principaux systèmes d'exploitation (Windows, Linux, OS X). Être flexible signifie également que
le développement rapide de Kivy lui permet des'adapter rapidement aux nouvelles technologies. Plus d'une fois, nous avons
ajouté la prise en charge de nouveaux périphériques externes et protocoles logiciels, parfois même avant leur sortie. Enfin, Kivy
est également flexible dans la mesure où il est possible de l'utiliser en combinaison avec un grand nombre de solutions tierces
différentes. Par exemple, sous Windows, nous prenons en charge WM_TOUCH, ce qui signifie que tout appareil doté des pilotes
Windows 7 Pen & Touchjuste travailler avec Kivy. Sur OS X, vous pouvez utiliser les appareils compatibles Multi-Touch d'Apple,
tels que les trackpads et les souris. Sous Linux, vous pouvez utiliser les événements d'entrée du noyau HID. En plus de cela, nous
prenons en charge TUIO (Tangible User Interface Objects) et un certain nombre d'autres sources d'entrée.
1.1.4 Concentré
Kivy est concentré. Vous pouvez écrire une application simple avec quelques lignes de code. Les programmes Kivy sont créés en
utilisant lePython langage de programmation, qui est incroyablement polyvalent et puissant, mais facile à utiliser. De plus, nous
avons créé notre propre langage de description, leLangue Kivy, pour créer des interfaces utilisateur sophistiquées. Ce langage
vous permet de paramétrer, connecter et organiser rapidement les éléments de votre application. Nous pensons que vous
permettre de vous concentrer sur l'essence de votre application est plus important que de vous forcer à modifier les paramètres
du compilateur. Nous avons enlevé ce fardeau de vos épaules.
1.1.5 Financé
Kivy est activement développé par des professionnels dans leur domaine. Kivy est une solution influencée par la communauté,
développée par des professionnels et soutenue commercialement. Certains de nos principaux développeurs développent Kivy pour
gagner leur vie. Kivy est là pour rester. Ce n'est pas un petit projet étudiant en voie de disparition.
1.1.6 Gratuit
Kivy est libre d'utilisation. Vous n'avez pas à payer pour cela. Vous n'avez même pas à payer pour cela si vous gagnez de
l'argent en vendant une application qui utilise Kivy.
6
CHAPITRE
DEUX
CONTRIBUANT
Il existe de nombreuses façons de contribuer à Kivy. Les correctifs de code ne sont qu'une chose parmi d'autres que vous pouvez
soumettre pour aider le projet. Nous accueillons également les commentaires, les rapports de bogues, les demandes de fonctionnalités,
les améliorations de la documentation, la publicité et le plaidoyer, les tests, les contributions graphiques et bien d'autres idées. Parlez-
nous simplement si vous voulez aider, et nous vous aiderons à nous aider.
2.1 Débats
Les discussions autour du développement de Kivy ont lieu sur les problèmes de Github et les demandes d'extraction pour des choses
spécifiques. Pour les choses qui ne rentrent pas dans l'un ou l'autre, des discussions ont lieu sur le#dev Chaîne Discord, et sur le groupe
google kivy-dev. N'hésitez pas à venir demander conseil si vous n'êtes pas sûr de la manière de contribuer, ou si vous souhaitez avoir la
confirmation que vos idées s'intègrent dans le projet avant de travailler dessus. Si vous souhaitez demander - ou contribuer - un soutien,
vous pouvez rejoindre le#supporter la chaîne Discord, et le groupe google des utilisateurs de kivy.
Dans l'intérêt de favoriser une communauté ouverte et accueillante, nous, en tant que contributeurs et mainteneurs, devons
nous assurer que la participation à notre projet et à nos projets frères est une expérience positive et sans harcèlement pour tout
le monde.
En tant que tel, il est essentiel que toutes les interactions soient menées d'une manière véhiculant le respect, l'ouverture d'esprit
et la gratitude. Pour une discussion plus complète de ces lignes directrices, veuillez vous référer auEngagement des
contributeurs. Ce document fournit une description précise de ce que l'on attend de vous, à la fois en tant que développeur
principal ou en tant que contributeur débutant.
2.3 Commentaires
C'est de loin le moyen le plus simple de contribuer à quelque chose. Si vous utilisez Kivy pour votre propre projet, n'hésitez pas à
partager. Il n'est évidemment pas nécessaire que ce soit une application d'entreprise haut de gamme. C'est juste
incroyablement motivant de savoir que les gens utilisent les choses que vous développez et ce que cela leur permet de faire. Si
vous avez quelque chose à nous dire, n'hésitez pas. Les captures d'écran et les vidéos sont également les bienvenues ! Nous
nous intéressons également aux problèmes que vous avez rencontrés au démarrage. N'hésitez pas à signaler tous les obstacles
que vous avez rencontrés, tels que des documents manquants, des instructions trompeuses ou similaires. Nous sommes
perfectionnistes, donc même si ce n'est qu'une faute de frappe, faites-le nous savoir.
sept
2.4 Signaler un problème
Si vous avez trouvé quelque chose qui ne va pas, un plantage, une erreur de segmentation, une documentation manquante, une orthographe incorrecte ou simplement des
[kivy]
log_level = déboguer
3. Ouvrir https://github.com/kivy/kivy/issues/
4. Définissez le titre de votre problème
5. Expliquez exactement ce qu'il faut faire pour reproduire le problème et collez le lien de la sortie publiée sur
http://gist.github.com/
Si vous vous sentez à la hauteur, vous pouvez également essayer de résoudre le bogue et contribuer en nous envoyant le patch :) Lisez la
section suivante pour savoir comment procéder.
Les contributions au code (patchs, nouvelles fonctionnalités) sont le moyen le plus évident d'aider au développement du projet. Étant
donné que cela est si courant, nous vous demandons de suivre notre flux de travail pour travailler le plus efficacement possible avec
nous. Le respect de notre flux de travail garantit que votre contribution ne sera pas oubliée ou perdue. De plus, votre nom sera toujours
associé au changement que vous avez effectué, ce qui signifie essentiellement une renommée éternelle dans notre histoire de code (vous
pouvez vous désinscrire si vous ne le souhaitez pas).
• Si vous ne l'avez pas encore fait, lisez le PEP8 sur le style de codage en python.
• Activez le pep8 et d'autres vérifications de base sur les commits git comme ceci :
faire un crochet
Cela transmettra le code ajouté à la zone de staging git (sur le point d'être validé) via un programme de vérification lorsque vous
effectuez une validation, et garantira que vous n'avez pas introduit d'erreurs de style. Si vous l'avez fait, le commit sera rejeté :
veuillez corriger les erreurs et réessayer.
Le vérificateur utilisé est pré-engager. Si vous devez ignorer une vérification particulière, consultezDocumentation, TLDR
étant ce qui met SKIP=nom du crochet devant de git commit sautera ce crochet, le nom du crochet incriminé est affiché
lorsqu'il échoue.
8
2.5.2 Performances
• Les parties gourmandes en CPU de Kivy sont écrites en cython : si vous faites beaucoup de calculs, pensez à
l'utiliser aussi.
Nous utilisons git comme système de contrôle de version pour notre base de code. Si vous n'avez jamais utilisé git ou un DVCS
similaire (ou même n'importe quel VCS) auparavant, nous vous suggérons fortement de jeter un œil à l'excellente
documentation disponible pour git en ligne. leLivre de la communauté Git ou la Vidéos Git sont deux excellents moyens
d'apprendre git. Faites-nous confiance lorsque nous disons que git est un excellent outil. Cela peut sembler intimidant au début,
mais après un certain temps, vous l'aimerez (espérons-le) autant que nous. Cependant, vous enseigner git dépasse largement le
cadre de ce document.
Aussi, nous utilisons GitHub pour héberger notre code. Dans ce qui suit, nous supposerons que vous disposez d'un compte
GitHub (gratuit). Bien que cette partie soit facultative, elle permet une intégration étroite entre vos correctifs et notre base de
code en amont. Si vous ne souhaitez pas utiliser GitHub, nous supposons que vous savez de toute façon ce que vous faites.
Voici donc la configuration initiale pour commencer avec notre flux de travail (vous n'avez besoin de le faire qu'une seule fois pour
installer Kivy). En gros, vous suivez les instructions d'installation deInstallation de développement, mais vous ne clonez pas notre
référentiel, vous le forkez. Voici les étapes :
1. Connectez-vous à GitHub
3. Clonez votre fork de notre référentiel sur votre ordinateur. Votre fork aura le nom de télécommande git
'origin' et vous serez sur la branche 'master' :
5. Installez notre hook de pré-commit qui garantit que votre code ne viole pas notre guide de style en exécutant faire un crochet
depuis le répertoire racine de votre clone. Cela exécutera notre vérification du guide de style chaque fois que vous effectuerez un
commit, et s'il y a des violations dans les parties que vous avez modifiées, votre commit sera abandonné. Corrigez et réessayez.
Désormais, chaque fois que vous souhaitez créer un patch, vous suivez les étapes suivantes :
1. Vérifiez s'il existe un ticket dans notre outil de suivi des bogues pour le correctif ou la fonctionnalité et annoncez que
vous y travaillerez s'il n'a pas encore de responsable.
2. Créez une nouvelle branche nommée de manière appropriée dans votre référentiel local pour cette fonctionnalité ou
correction de bogue spécifique. (Garder une nouvelle branche par fonctionnalité garantit que nous pouvons
facilement extraire vos modifications sans extraire d'autres éléments qui ne sont pas censés être extraits.):
3. Modifiez le code pour faire ce que vous voulez (par exemple, corrigez-le).
9
4. Testez le code. Essayez de le faire même pour de petites corrections. Vous ne savez jamais si
vous avez introduit un bug étrange sans tester.
5. Effectuez un ou plusieurs commits atomiques minimaux par correctif ou par fonctionnalité. Moyenne minimale/
atomiquegarder le commit propre. Ne validez pas d'autres éléments qui n'appartiennent pas logiquement à ce
correctif ou à cette fonctionnalité. C'estne pas sur la création d'un commit par ligne modifiée. Utilisergit ajouter -p
si nécessaire.
6. Donnez à chaque commit un message de commit approprié, afin que les autres qui ne sont pas familiers
avec le sujet aient une bonne idée de ce que vous avez changé.
7. Une fois que vous êtes satisfait de vos modifications, extrayez notre référentiel en amont et fusionnez-le avec
votre référentiel local. Nous pouvons extraire vos données, mais puisque vous savez exactement ce qui a
changé, vous devez effectuer la fusion :
8. Poussez votre branche locale dans votre référentiel distant sur GitHub :
9. Envoyez un Demande de tirage avec une description de ce que vous avez modifié via le bouton dans
l'interface GitHub de votre référentiel. (C'est pourquoi nous avons initialement forké. Votre référentiel est lié
au nôtre.)
Avertissement: Si vous modifiez des parties de la base de code qui nécessitent une compilation, vous
devrez recompiler pour que vos modifications prennent effet. leFabriquer La commande le fera pour
vous (voir le Makefile si vous voulez savoir ce qu'il fait). Si vous devez nettoyer votre répertoire actuel
des fichiers compilés, exécutezrendre propre. Si vous voulez vous débarrasser tout fichiers qui ne sont
pas sous contrôle de version, exécutez faire distclean (Mise en garde: Si vos modifications ne sont pas
sous contrôle de version, cette commande les supprimera !)
Nous allons maintenant recevoir votre pull request. Nous vérifierons si vos modifications sont propres et logiques (si
vous nous en avez parlé avant de faire tout cela, nous vous aurons dit si cela a du sens ou non). Si c'est le cas, nous les
tirerons et vous obtiendrez un karma instantané. Félicitations, vous êtes un héros !
Les contributions de documentation suivent généralement le même workflow que les contributions de code, mais sont juste un peu plus
laxistes.
1. Forkez le référentiel.
1. Créez une nouvelle branche nommée de manière appropriée dans votre référentiel local :
dix
2. Modifiez la documentation avec votre correction ou amélioration.
faire du html
4. Donnez à chaque commit un message de commit approprié, afin que les autres qui ne sont pas familiers avec le sujet
aient une bonne idée de ce que vous avez changé.
5. Gardez chaque commit concentré sur un seul thème connexe. Ne commitez pas d'autres choses qui n'appartiennent pas
logiquement à cette mise à jour.
git pousser
7. Envoyez un Demande de tirage avec une description de ce que vous avez modifié via le bouton dans l'interface GitHub de
votre référentiel.
Nous ne vous demandons pas de vous embêter à corriger une seule faute de frappe, mais pour des contributions plus
complexes, veuillez suivre le flux de travail suggéré.
2.6.1 Docstrings
Chaque module/classe/méthode/fonction a besoin d'une chaîne de documentation, utilisez donc les mots-clés suivants le cas échéant :
•.. version ajoutée :: pour marquer la version dans laquelle la fonctionnalité a été ajoutée.
•.. version changée :: pour marquer la version dans laquelle le comportement de la fonction a été modifié.
•.. Remarque:: pour ajouter des informations supplémentaires sur l'utilisation de la fonctionnalité ou de la fonctionnalité associée.
•.. avertissement:: pour indiquer un problème potentiel que l'utilisateur pourrait rencontrer en utilisant la fonctionnalité.
Exemples:
11
Lorsque vous faites référence à d'autres parties de l'API, utilisez :
Remplacer évidemment classe de module et méthode avec leur vrai nom et en utilisant '.' pour séparer des modules se
référant à des modules imbriqués, par exemple :
faire du html
Si vous avez mis à jour votre installation de Kivy et que vous rencontrez des problèmes pour compiler des documents, exécutez :
Les documents seront générés dans docs/build/html. Pour plus d'informations sur le formatage docstring, veuillez vous
référer à la page officielle Documentation Sphinx.
Pour l'équipe de test, nous avons le document Tests unitaires qui explique comment fonctionnent les tests unitaires Kivy et comment
vous pouvez créer les vôtres. Utiliser la même approche que leFlux de travail de code soumettre de nouveaux tests.
Les tests sont situés dans le kivy/tests dossier. Si vous trouvez un bogue dans Kivy, une bonne chose à faire peut être d'écrire un
cas minimal montrant le problème et de demander aux développeurs principaux si le comportement affiché est voulu ou un vrai
bogue. Si vous écrivez votre code en tant queTest de l'unité , cela empêchera le bug de revenir inaperçu à l'avenir et fera de Kivy
un projet meilleur et plus fort. Écrire un test unitaire peut être un très bon moyen de se familiariser avec Kivy tout en faisant
quelque chose d'utile.
• Tests unitaires non graphiques : ce sont des tests unitaires standards qui peuvent s'exécuter dans une console
• Tests unitaires graphiques : ils nécessitent un contexte GL et, si demandé, fonctionnent via la comparaison d'images
Pour pouvoir exécuter des tests unitaires, vous devez installer pytest (https://pytest.org/) et la couverture (http://
nedbatchelder.com/code/coverage/). Vous pouvez utiliser pip pour cela :
12
sudo pip installer la couverture pytest
faire un test
Comment ça fonctionne
Tous les tests sont situés dans kivy/tests, et le nom du fichier commence par test_<nom>.py. Pytest rassemblera
automatiquement tous les fichiers et classes dans ce dossier et les utilisera pour générer des cas de test.
Pour écrire un test, créez un fichier qui respecte la dénomination précédente, puis commencez par ce modèle :
déf test_AAAA(soi):
# placez votre cas de test ici une =
1
soi.affirmerÉgal(une, 1)
Remplacer XXX par un nom approprié qui couvre vos cas de test, puis remplacez « YYY » par le nom de votre test.
Si vous avez des doutes, vérifiez comment les autres tests ont été rédigés.
faire un test
pytest kivy/essais/test_votretestcase.py
ou inclure ce simple unittest.main() appeler à la fin du fichier et lancer le test avec python
test_yourtestcase.py:
si __Nom__ == '__principale__':
Test de l'unité.principale()
Alors que les tests unitaires simples sont parfaits et utiles pour garder les choses granulaires, dans certains cas, nous
devons tester Kivy après la création de la fenêtre GL pour interagir avec les graphiques, les widgets et tester des
éléments plus avancés tels que les widgets, les modules, divers cas d'entrée et l'interaction avec tout ce qui ne devient
disponible qu'une fois la fenêtre créée et Kivy correctement initialisé.
Ces tests sont exécutés de la même manière que les tests unitaires ordinaires, c'est-à-dire avec pytest ou via
unittest.main().
Voici deux exemples similaires avec différentes approches d'exécution de l'application. Dans le premier, vous configurez
les éléments requis manuellement et ledémolir() du Test d'unité graphique ne peut essayer de le nettoyer qu'après
avoir :
13
à partir de kivy.tests.common importer Test d'unité graphique
déf test_runtouchapp(soi):
# approche non intégrée à partir de kivy.app
importer exécuterTouchApp à partir de bouton
kivy.uix importer Bouton
bouton = Bouton()
exécuterTouchApp(bouton)
# vos assertions
soi.affirmerÉgal(la fenêtre.enfants[0], soi. bouton)
affirmerÉgal(
la fenêtre.enfants[0].la taille, la
fenêtre.la taille
)
Dans le deuxième cas de test, les deux mettre en place() et démolir() travailler avec GraphicUnitTest.render(). Voici la configuration de
base qu'il effectue automatiquement :
• Seule la configuration par défaut est utilisée pendant le test, elle est limitée par le
KIVY_USE_DEFAULTCONFIG variable d'environnement
• Toute entrée (souris/tactile/. . . ) est supprimé et si vous avez besoin de le tester, moquez-vous ou ajoutez-le manuellement
Avertissement: N'utilisez PAS de nombres absolus dans vos tests pour préserver la fonctionnalité dans toutes les résolutions. Au
lieu de cela, utilisez par exemple la position ou la taille relative et multipliez-la par leLa taille de la fenêtre dans ton essai.
déf test_render(soi):
à partir de bouton kivy.uix importer Bouton
14
(suite de la page précédente)
Boucle d'événement.assurer_fenêtre() la
fenêtre = Boucle d'événement.la fenêtre
toucher = UnitTestTouch(
* [s / 2.0 pour s dans la fenêtre.Taille]
)
soi.assertTrue(bouton.test_publié)
si __Nom__ == '__principale__':
importer Test de l'unité
Test de l'unité.principale()
Noter: Assurez-vous de vérifier la source de kivy.tests.common avant d'écrire des cas de test complets.
tests unitaires GL
Les tests unitaires GL sont plus difficiles. Vous devez savoir que même si OpenGL est un standard, la sortie/le rendu ne
l'est pas. Cela dépend de votre GPU et du pilote utilisé. Pour ces tests, le but est de sauvegarder la sortie du rendu à
l'image X, et de la comparer à une image de référence.
Noter: Actuellement, la comparaison d'images se fait par pixel. Cela signifie que l'image de référence que vous générez ne sera
correcte que pour votre GPU/pilote. Si quelqu'un peut implémenter la comparaison d'images avec le support "delta", les
correctifs sont les bienvenus :)
Pour exécuter les tests unitaires GL, vous devez créer un répertoire :
mkdir kivy/essais/résultats
KIVY_UNITTEST_SCREENSHOTS=1 faire un test
Le répertoire des résultats contiendra toutes les images de référence et les images générées. Après la première
exécution, si le répertoire des résultats est vide, aucune comparaison ne sera effectuée. Il utilisera les images générées
comme référence. Après la deuxième exécution, toutes les images seront comparées aux images de référence.
Un fichier html est disponible pour montrer la comparaison avant/après le test, et un extrait du test
unitaire associé. Il sera généré à :
kivy/tests/build/index.html
15
Noter: Le répertoire de construction est nettoyé après chaque appel à faire un test. Si vous ne le souhaitez pas, utilisez simplement la commande
pytest.
L'idée est de créer un widget racine, comme vous le feriez dans construire(), ou dans kivy.base.runTouchApp(). Vous
donnerez ce widget racine à une fonction de rendu qui capturera la sortie dans des images X.
Voici un exemple:
déf test_ellipse(soi):
à partir de kivy.uix.widget importer Widget à partir
de kivy.graphics importer Ellipse, Couleur r = soi.
rendre
# ou en 10 images r(
largeur, dix)
Chaque appel à auto.rendu (ou r dans notre exemple) va générer une image nommée comme suit :
nombre d'appels représente le nombre de fois que auto.rendu est appelé à l'intérieur de la fonction de test.
Vous pouvez facilement remplacer l'image de référence par une nouvelle si vous le souhaitez.
16
Rapports de couverture
La couverture est basée sur l'exécution des tests précédents. Les statistiques sur la couverture du code sont automatiquement
calculées lors de l'exécution. Vous pouvez générer un rapport html de la couverture avec la commande :
Faire la couverture
2.8 GSOC
introduction
Kivy est une bibliothèque Python open source multiplateforme, conviviale et accélérée par GPU pour le développement
rapide d'applications utilisant des interfaces utilisateur innovantes, telles que des applications multi-touch.
• Le Pince wrapper Python indépendant de la plate-forme pour les API dépendantes de la plate-forme.
• KivEnt - Un moteur de jeu 2D qui fournit des méthodes optimisées pour gérer de grandes quantités de données visuelles
dynamiques.
Dans l'ensemble, ces projets permettent à l'utilisateur de créer des applications pour tous les principaux systèmes d'exploitation qui
utilisent toutes les API natives présentes. Notre objectif est de permettre le développement d'applications Python qui s'exécutent partout
sur la même base de code et qui utilisent des API et des fonctionnalités dépendantes de la plate-forme auxquelles les utilisateurs de
systèmes d'exploitation spécifiques s'attendent.
Selon le projet que vous choisissez, vous devrez peut-être connaître Cython, OpenGL ES2, Java, Objective-C ou C en plus
de Python. Nous utilisons massivement Cython et OpenGL pour les performances de calcul et graphiques là où cela
compte, et les autres langages sont généralement impliqués dans l'accès aux API au niveau du système d'exploitation
ou du fournisseur.
Nous espérons participer au Google Summer of Code 2017. Cette page présente quelques idées de projets
GSoC et les directives correspondantes pour les étudiants contribuant au framework Kivy.
17
Exigences
Il est supposé que l'étudiant entrant répond à certaines exigences de base, comme souligné ici :
• À l'aise avec git et github (Kivy et ses projets sœurs sont tous gérés sur github) Si vous n'avez jamais
utilisé github auparavant, cela peut vous intéresser Didacticiel.
• Dispose d'outils/d'un environnement adaptés à Kivy ou au projet jumeau sur lequel vous allez travailler. Par exemple, pour
pouvoir travailler sur PyOBJus, vous auriez besoin d'accéder à un appareil iOS, OS X avec Xcode et une licence de
développeur, pour travailler sur PyJNIus, vous auriez besoin d'un appareil Android, et pour travailler sur plier, vous auriez
besoin d'un accès au matériel pour les deux plates-formes.
Des compétences supplémentaires souhaitées peuvent être répertoriées avec des projets spécifiques.
Familiarisez-vous avec le guide de contribution Nous pouvons vous aider à vous mettre à niveau, mais les étudiants
démontrant leurs capacités à l'avance auront la préférence.
Comment commencer
Pour Kivy, le plus simple est de suivre les instructions d'installation de la version de développement pour votre
plateforme spécifique :
http://kivy.org/docs/installation/installation.html#development-version
Pour le reste, il suffit généralement d'installer le projet concerné depuis git et de l'ajouter à votre PYTHON-PATH.
Idées de projets
Voici quelques idées prospectives provenant de l'équipe de développement Kivy, si aucun de ces projets ne vous
intéresse, venez nous parler dans #kivy-dev d'une idée de projet qui vous est propre.
Ces projets devraient convenir à toute personne connaissant Python au niveau universitaire et nécessitant peu de connaissances
sur les spécificités de la plate-forme.
Projets intermédiaires
Ces projets peuvent impliquer une connaissance superficielle de plusieurs détails au niveau du système d'exploitation, certaines
interactions OpenGL ou d'autres sujets qui peuvent être un peu hors de la timonerie du Pythonista moyen.
Joueur :
La description: Plyer est une API Python indépendante de la plate-forme pour utiliser les fonctionnalités couramment trouvées
sur les plates-formes de bureau et mobiles prises en charge par Kivy. L'idée est de fournir une API stable à l'utilisateur pour
accéder aux fonctionnalités de son ordinateur de bureau ou de son appareil mobile.
18
L'étudiant remplacerait certains .Java code actuellement dans le projet p4a à un endroit plus approprié dans
Plyer. En outre, l'étudiant travaillerait à l'amélioration de l'accès aux fonctionnalités spécifiques à la plate-
forme via Plyer, y compris l'accessibilité, Bluetooth Low Energy, l'accès et la modification des contacts, le
partage, NFC, navigateur intégré à l'application, Wi-Fi (activer, désactiver, accès à Wi- Services Fi (Wi-Fi direct,
accessibilité du réseau, informations IP actuelles sur le réseau, etc.), capture de l'appareil photo (vidéo),
affichage de l'appareil photo, intégration de Google Play, interface de lancement d'appel téléphonique,
interface sms, géolocalisation, interaction avec les notifications, internationalisation (I18N ) et toutes les
implémentations de plate-forme manquantes des fonctionnalités existantes.
Sous le capot, vous utiliserez PyJNIus sur Android, PyOBJus sur OS X et iOS, ctypes sur Windows et les
API natives sur Linux. Cela inclurait probablement également l'amélioration de PyOBJus et PyJNIus
pour gérer les interfaces qu'ils ne peuvent pas actuellement.
Les références:
• https://github.com/kivy/plyer
• https://github.com/kivy/pyjnius
• https://github.com/kivy/pyobjus
• https://github.com/kivy/python-for-android
• https://github.com/kivy/kivy-ios
Résultat attendu : Un résultat positif inclurait le déplacement du code Java/PyOBJus
de p4a/kivy-ios à plier et mise en place de tout ou partie des nouvelles façades à
décider avec l'étudiant.
• Mentors: Akshay Arora
• Exigences: Accès à Linux, Windows, OS X, appareil iOS, appareil Android.
• Niveau de tâche: Intermédiaire
La description: Actuellement, Kivy ne prend pas en charge le remodelage des alphabets tels que l'arabe, le per-
sian, thaï ou devanagari. La solution est d'intégrer un moteur de mise en forme et de mise en page de texte
(Pango et Harfbuzz). Vous devrez vous assurer que Pango et Harfbuzz peuvent être compilés sur chaque
plate-forme et les intégrer en tant que fournisseur de texte de base.
La deuxième partie du même projet impliquerait la prise en charge des polices de secours. Si un caractère/glyphe particulier
est manquant, nous affichons actuellement une boîte []. La solution pour cela impliquerait soit d'utiliser une API de système
d'exploitation si disponible, soit de maintenir une table de hachage pour les polices par défaut sur chaque système
d'exploitation qui peut être utilisée pour le repli de glyphe.
Les références:
• http://www.pango.org
• https://www.freedesktop.org/wiki/Software/HarfBuzz/
• https://github.com/kivy/kivy/tree/master/kivy/core/text
Résultat attendu : Prise en charge du remplacement des polices et du remodelage du texte dans Kivy, recettes de compilation
pour Python-For-Android et packaging sur les plates-formes de bureau.
• Compétences désirées: Familiarité avec le rendu de texte, Pango, HarfBuzz et l'abstraction du fournisseur
de Kivy.
19
Projets avancés
Ces projets peuvent impliquer une connaissance très approfondie des éléments internes existants de Kivy, les détails délicats de
la compilation multiplateforme ou d'autres sujets assez avancés. Si vous êtes à l'aise avec les composants internes de Python,
que vous travaillez avec du code C et que vous utilisez Cython pour créer vos propres extensions C, ces projets peuvent vous
intéresser.
La description: KivEnt est un moteur de jeu modulaire basé sur des composants d'entités construit sur Kivy.
KivEnt fournit une approche hautement performante pour créer des jeux en Python qui évite certains des
pires frais généraux de Python en utilisant des constructions Cython spécialisées.
Les références:
• http://chipmunk-physics.net/
• https://github.com/kivy/kivent
Résultat attendu : Un résultat positif implique qu'un nouveau module kivent_tiled soit re-
loué pour le moteur de jeu KivEnt.
• Compétences désirées: Familiarité avec les concepts mathématiques liés à Cython, Python et au développement de jeux.
Le travail sur un compilateur kv a déjà bien avancé, en fait un PR au stade pré-alpha est actuellement
ouvert. Cependant, il n'est pas synchronisé avec la base de code actuelle en raison de certains
changements de kv non liés entre-temps. En outre, ce PR nécessiterait une réécriture importante
pour rendre les choses plus modulaires, autonomes et extensibles. Il y a donc encore beaucoup de
travail à faire dessus.
La thématisation a également été un problème prépatuel dans Kivy, un compilateur KV peut aider à implémenter
des liaisons qui facilitent la thématisation.
Les références:
• https://kivy.org/docs/guide/lang.html
20
• https://github.com/kivy/kivy/pull/3456
• https://github.com/kivy/kivy/wiki/KEP001:-Instantiate-things-other-than-widgets-from-kv
• https://github.com/kivy/kivy/issues/691
• https://github.com/kivy/kivy/issues/2727
Résultat attendu : Un résultat positif serait un compilateur qui compile le code kv
en code python. Le compilateur doit être modulaire et extensible afin que nous puissions
continuer à améliorer le langage kv. Le compilateur doit avoir les options de débogage/
optimisation communes. Le code compilé doit également être lisible par l'homme afin que les
problèmes puissent être retracés jusqu'au code kv d'origine. Le compilateur devrait également
remplacer le compilateur d'exécution KV actuel et nécessiterait des tests approfondis.
• Compétences désirées: Familiarité avec Cython, Python et Kivy. Une connaissance des concepts
informatiques et des structures de données typiques est également souhaitée.
Toute communication doit se faire via des canaux publics, les e-mails privés et les messages privés Discord sont
découragés.
Vous pouvez également essayer de nous contacter sur Discord, pour obtenir les poignées Discord des développeurs mentionnés ci-dessus, visitez
https://kivy.org/#aboutus.
La plupart de nos développeurs sont situés en Europe, en Inde et en Amérique du Nord, alors gardez à l'esprit les heures d'éveil typiques
de ces régions.
Si vous souhaitez participer en tant qu'étudiant et maximiser vos chances d'être accepté, commencez à nous parler dès
aujourd'hui et essayez de résoudre quelques petits problèmes pour vous habituer à notre flux de travail. Si nous savons que
vous pouvez bien travailler avec nous, vous aurez de bien meilleures chances d'être sélectionné.
• Contribuez ! Kivy aimerait voir comment vous vous engagez dans le processus de développement. Jetez un œil au traqueur
de problèmes pour un projet Kivy qui vous intéresse et soumettez une Pull Request. Il peut s'agir d'un simple bug ou d'un
changement de documentation. Nous cherchons à avoir une idée de votre façon de travailler, pas à évaluer vos capacités.
Ne vous inquiétez pas d'essayer de choisir quelque chose pour nous impressionner.
• Choisissez une idée que vous jugez intéressante dans la liste d'idées ou proposez votre propre idée.
21
• Fais quelques recherches toi-même. GSoC est une question de donner et recevoir, pas seulement une interaction unilatérale. Il
s'agit de vous essayer d'atteindre les objectifs convenus avec notre soutien. La force motrice principale dans tout cela devrait être,
évidemment, vous-même. De nombreux étudiants surgissent et demandent ce qu'ils doivent faire. Vous devez baser cette
décision sur vos intérêts et vos compétences. Montrez-nous que vous êtes sérieux et prenez l'initiative.
• Rédiger un brouillon proposition sur ce que tu veux faire. Incluez ce que vous comprenez de l'état
actuel du projet, ce que vous aimeriez améliorer, comment, etc.
• Être patient! Surtout sur Discord. Nous essaierons de vous joindre si nous sommes disponibles. Sinon, envoyez un
e-mail et attendez. La plupart des questions sont déjà répondues dans les documents ou ailleurs et peuvent être
trouvées avec quelques recherches. Vos questions doivent refléter le fait que vous avez réellement réfléchi à ce
que vous demandez et effectué des recherches rudimentaires.
• Surtout n'oubliez pas de vous amuser et d'interagir avec la communauté. La communauté est une partie aussi importante
de l'Open Source que le code lui-même.
• Tous les étudiants doivent rejoindre quotidiennement les canaux #support et #dev Discord, c'est ainsi que l'équipe de
développement communique à la fois en interne et avec les utilisateurs.
• Vous et vos mentors vous mettrez d'accord sur des jalons de deux semaines pour la durée de l'été.
• Le développement se fera dans votre fork de la branche master de Kivy, nous attendons de vous que vous soumettiez au
moins un PR par semaine depuis votre branche dans une branche qui vous est réservée dans le repo primaire. Ce sera
votre forum pour signaler les progrès ainsi que pour documenter toutes les difficultés que vous pourriez avoir
rencontrées.
• Manquer 2 RP hebdomadaires ou 2 jalons entraînera votre échec à moins qu'il n'y ait eu des circonstances
atténuantes. Si quelque chose survient, veuillez en informer vos mentors dès que possible. Si une étape
semble hors de portée, nous travaillerons avec vous pour réévaluer les objectifs.
• Vos modifications seront fusionnées dans le master une fois le projet terminé et nous avons
minutieusement testé sur chaque plate-forme pertinente.
22
CHAPITRE
TROIS
FAQ
Il y a un certain nombre de questions auxquelles il faut constamment répondre. Le document suivant tente de répondre à
certaines d'entre elles.
Si Kivy ne peut pas instancier un fournisseur principal de Windows (principalement SDL2), vous le verrez. Le problème sous-jacent dépend
de beaucoup de choses :
• Vérifiez que votre pilote graphique prend en charge OpenGL 2.1 au minimum. Sinon, Kivy ne peut pas courir.
• Si vous utilisez Windows et ANGLE (KIVY_GL_BACKEND=angle_sdl2), vérifiez que vous avez le support
DirectX 9.
• Si votre plate-forme ne prend pas en charge OpenGL, SDL2 ne peut pas initialiser OpenGL.
• Ne mélangez pas l'architecture des dépendances (par exemple extensions Python 64 bits et 32 bits/SDL2)
• Ne mélangez pas l'installation de Python : par exemple, si vous avez installé Python et Anaconda, le Python réellement
exécuté peut être différent de ce que vous pensez. De même, si vous avez plusieurs versions de Python disponibles sur le
CHEMIN, ils peuvent s'affronter.
• Vérifiez votre PATH pour vous assurer que les autres programmes qu'il contient ne fournissent pas les mêmes DLL que Kivy/Python, sinon des
problèmes peuvent se produire.
– Cela se produit généralement si un autre programme qui utilise des dépendances similaires à Kivy s'ajoute au
CHEMIN de sorte que les dépendances de Kivy se heurtent aux leurs.
– Lisez s'il vous plaît cette et cette pour plus de détails sur CHEMIN.
– Le meilleur outil pour résoudre ce problème est avec Dépendance Walker expliqué ici et ici.
– Mais assurez-vous de le lancer à partir de l'environnement identique dans lequel vous démarrez Python.
• Peut-être que vos pilotes ont des symboles OpenGL manquants ? Essayez de passer à un autre backend
graphique avecKIVY_GL_BACKEND.
23
3.1.2 Erreur fatale de Python : (pygame parachute) Défaut de segmentation
La plupart du temps, ce problème est dû à l'utilisation d'anciens pilotes graphiques. Installez le dernier pilote graphique
disponible pour votre carte graphique, et cela devrait être ok.
Sinon, cela signifie que vous avez probablement déclenché du code OpenGL sans contexte OpenGL disponible. Si vous
chargez des images, des atlas, en utilisant des instructions graphiques, vous devez d'abord générer une fenêtre :
# méthode 2
à partir de kivy.core.window importer Fenêtre
Sinon, veuillez signaler un problème détaillé sur github en suivant les instructions dans le Signaler un problème partie
de la Contribuant Documentation. C'est très important pour nous car ce genre d'erreur peut être très difficile à
déboguer. Donnez-nous toutes les informations que vous pouvez donner sur votre environnement et votre exécution.
Votre carte graphique ou ses pilotes sont peut-être trop vieux. Mettez à jour vos pilotes graphiques vers la dernière version disponible et
réessayez.
Si vous utilisez Kivy depuis notre version de développement, vous devez le compiler avant de l'utiliser. Dans le répertoire kivy, faites :
faire force
Dans le cas de l'erreur du mode « Stockage de masse USB », et si vous ne souhaitez pas continuer à débrancher l'appareil, définissez
l'option USB sur Alimentation.
24
3.2.2 Crash lors de l'interaction tactile sur Android 2.3.x
Il y a eu des rapports de plantages sur les appareils basés sur Adreno 200/205. Sinon, les applications fonctionnent correctement mais se
bloquent lorsqu'elles interagissent avec / via l'écran.
Ces rapports mentionnaient également le problème en cours de résolution lors du passage à une ROM ICS ou supérieure.
3.2.3 Est-il possible d'avoir une application kiosque sur Android 3.0 ?
Thomas Hansen a écrit une réponse détaillée sur la liste de diffusion kivy-users :
https://groups.google.com/d/msg/kivy-users/QKoCekAR1c0/yV-85Y_iAwoJ
Fondamentalement, vous devez rooter l'appareil, supprimer le package SystemUI, ajouter quelques lignes à la configuration
XML, et vous avez terminé.
Bien qu'il porte le même nom, le python-for-android de Kivy n'est pas lié au projet python-for-android de SL4A, Py4A ou
android-python27. Ce sont des projets distinctement différents avec des objectifs différents. Vous pourrez peut-être
utiliser Py4A avec Kivy, mais aucun code ou effort n'a été fait pour le faire. L'équipe Kivy estime que notre python-for-
android est la meilleure solution pour nous à l'avenir, et les tentatives d'intégration et de prise en charge de Py4A ne
sont pas une bonne utilisation de notre temps.
Essayons de donner une réponse complète ; s'il vous plaît soyez indulgent avec nous.
Python est un langage très agile qui vous permet de faire beaucoup de choses en peu de temps (par comparaison). Pour de
nombreux scénarios de développement, nous préférons fortement écrire notre application rapidement dans un langage de haut
niveau tel que Python, la tester, puis éventuellement l'optimiser.
Mais qu'en est-il de la vitesse ? Si vous comparez les vitesses d'exécution des implémentations pour un certain ensemble
d'algorithmes (en particulier le calcul des nombres), vous constaterez que Python est beaucoup plus lent que, disons, C++.
Maintenant, vous êtes peut-être encore plus convaincu que ce n'est pas une bonne idée dans notre cas d'utiliser Python.
Dessiner des graphiques sophistiqués (et nous ne parlons pas ici de l'OpenGL de votre grand-mère) est assez coûteux en calcul
et étant donné que nous voulons souvent le faire pour des expériences utilisateur riches, ce serait un argument juste. Mais,
dans pratiquement tous les cas, votre application finit par passer la plupart du temps (de loin) à exécuter la même partie du
code. Dans Kivy, par exemple, ces parties sont la répartition des événements et le dessin graphique. Maintenant, Python vous
permet de faire quelque chose pour rendre ces parties beaucoup plus rapides.
En utilisant Cython, vous pouvez compiler votre code jusqu'au niveau C, et à partir de là, votre compilateur C habituel
optimise les choses. C'est un processus assez simple et si vous ajoutez quelques astuces à votre code, le résultat devient
encore plus rapide. Nous parlons d'une accélération des performances d'un facteur compris entre 1x et jusqu'à plus de
1000x (cela dépend beaucoup de votre code). Chez Kivy, nous l'avons fait pour vous et avons implémenté les portions de
notre code, où l'efficacité est vraiment critique, au niveau C.
Pour le dessin graphique, nous utilisons également les GPU d'aujourd'hui qui sont, pour certaines tâches telles que la
rastérisation graphique, beaucoup plus efficace qu'un CPU. Kivy fait tout ce qui est raisonnable sur le GPU pour maximiser les
performances. Si vous utilisez notre API Canvas pour faire le dessin, il existe même un compilateur que nous avons inventé qui
optimise automatiquement votre code de dessin. Si vous conservez votre dessin principalement sur le GPU, une grande partie
de la vitesse d'exécution de votre programme n'est pas déterminée par le langage de programmation utilisé, mais par le
matériel graphique que vous lui lancez.
25
Nous pensons que ces optimisations (et d'autres) que Kivy fait pour vous rendent déjà la plupart des applications assez
rapides de loin. Souvent, vous voudrez même limiter la vitesse de l'application afin de ne pas gaspiller de ressources.
Mais même si cela ne suffit pas, vous avez toujours la possibilité d'utiliser Cython pour votre propre code afin detrès
accélérer.
Faites-nous confiance lorsque nous disons que nous avons réfléchi très attentivement. Nous avons effectué de nombreux tests
de performances et proposé des optimisations intelligentes pour que votre application fonctionne sans problème.
Oui! Depuis la version 1.8.0, Kivy prend en charge à la fois Python >= 2.7 et Python >= 3.4 avec la même base de code. Python 3
est également désormais pris en charge par python-for-android et kivy-ios.
Nos développeurs sont des professionnels et sont assez avertis dans leur domaine d'expertise. Cependant, avant
l'arrivée de Kivy, il y avait (et est toujours) un projet nommé PyMT qui était dirigé par nos principaux développeurs. Nous
avons beaucoup appris de ce projet pendant que nous l'avons développé. En plus de deux ans de recherche et
développement, nous avons trouvé de nombreuses façons intéressantes d'améliorer la conception de notre cadre. Nous
avons effectué de nombreux tests de performances et, en fin de compte, pour atteindre la grande vitesse et la flexibilité
dont dispose Kivy, nous avons dû réécrire une assez grande partie de la base de code, ce qui en fait une décision
rétrocompatible mais pérenne. Les plus notables sont les augmentations de performances, qui sont tout simplement
incroyables. Kivy démarre et fonctionne tellement plus rapidement, en raison de ces optimisations lourdes. Nous avons
également eu l'opportunité de travailler avec des entreprises et des associations utilisant PyMT. Nous avons pu tester
notre produit sur une grande diversité de configurations et avons fait fonctionner PyMT sur toutes. Écrire un système
comme Kivy ou PyMT est une chose. Le faire fonctionner dans toutes ces conditions différentes en est une autre. Nous
avons une bonne expérience ici et avons apporté nos connaissances à Kivy.
De plus, étant donné que certains de nos développeurs principaux ont décidé d'abandonner leurs emplois à temps plein et de se
tourner complètement vers ce projet, il a été décidé qu'une base plus professionnelle devait être posée. Kivy est cette fondation.
C'est censé être un produit stable et professionnel. Techniquement, Kivy n'est pas vraiment un successeur de PyMT car il n'y a
pas de chemin de migration facile entre eux. Cependant, l'objectif est le même : produire des applications de haute qualité pour
de nouvelles interfaces utilisateur. C'est pourquoi nous encourageons tout le monde à baser de nouveaux projets sur Kivy au
lieu de PyMT. Le développement actif de PyMT est au point mort. Les correctifs de maintenance sont toujours acceptés.
Oui, nous aimons les patchs. Cependant, afin d'assurer une intégration harmonieuse de vos précieuses modifications, assurez-
vous de lire nos directives de contribution. Évidemment, nous n'acceptons pas tous les patchs. Votre patch doit être cohérent
avec notre guide de style et, plus important encore, avoir du sens. Il est logique de nous parler avant de proposer des
changements plus importants, en particulier de nouvelles fonctionnalités.
Les étudiants potentiels demandent si nous participons au GSoC. La réponse claire est : En effet. :-)
Si vous souhaitez participer en tant qu'étudiant et maximiser vos chances d'être accepté, commencez à nous parler dès
aujourd'hui et essayez de résoudre des problèmes plus petits (ou plus gros, si vous le pouvez ;-) pour vous habituer à notre flux
de travail. Si nous savons que vous pouvez bien travailler avec nous, ce serait un gros plus.
26
• Lisez nos directives de contribution.
• Choisissez une idée qui vous semble intéressante dans la liste d'idées (voir le lien ci-dessus) ou proposez votre
propre idée.
• Fais quelques recherches toi-même. GSoC ne consiste pas à vous enseigner quelque chose et à vous faire payer pour cela.
Il s'agit de vous essayer d'atteindre les objectifs convenus par vous-même avec notre soutien. La force motrice principale
dans tout cela devrait être, évidemment, vous-même. De nombreux étudiants viennent et demandent ce qu'ils doivent
faire. Eh bien, nous ne savons pas parce que nous ne connaissons ni vos intérêts ni vos compétences. Montrez-nous que
vous êtes sérieux et prenez des initiatives.
• Rédigez une ébauche de proposition sur ce que vous voulez faire. Incluez ce que vous comprenez dans l'état actuel
(très grossièrement), ce que vous aimeriez améliorer et comment, etc.
• Être patient! Surtout sur Discord. Nous essaierons de vous joindre si nous sommes disponibles. Sinon, envoyez un
e-mail et attendez. La plupart des questions sont déjà répondues dans les documents ou ailleurs et peuvent être
trouvées avec quelques recherches. Si vos questions ne reflètent pas que vous avez réellement réfléchi à ce que
vous demandez, cela pourrait ne pas être bien reçu.
27
28
CHAPITRE
QUATRE
NOUS CONTACTER
Si vous avez trouvé un problème avec le code ou avez une demande de fonctionnalité, veuillez consulter notre Traqueur d'incidents. S'il
n'y a pas encore de problème qui correspond à votre demande, n'hésitez pas à en créer un nouveau. Veuillez vous assurer de recevoir les
e-mails que github envoie si nous commentons le problème au cas où nous aurions besoin de plus d'informations. Pour les bogues,
veuillez fournir toutes les informations nécessaires, comme le système d'exploitation que vous utilisez, lemessage d'erreur complet ou
tout autre journal, une description de ce que vous avez fait pour déclencher le bogue et quel était le bogue réel, ainsi que tout autre
élément susceptible de vous intéresser. Évidemment, nous ne pouvons vous aider que si vous nous dites précisément quel est le
problème réel.
4.2 Courrier
Pour les utilisateurs de notre framework, il existe une liste de diffusion pour les demandes d'assistance sur le kivy-users Google Group.
Utilisez cette liste si vous rencontrez des problèmes avec votre application basée sur Kivy. Nous avons également une liste de diffusion
pour les questions qui traitent du développement du code du cadre Kivy réel sur leGroupe Google kivy-dev.
4.3 Discorde
Discord est idéal pour la communication en temps réel, mais assurez-vous de attendre après avoir posé votre question. Si vous vous
inscrivez, demandez et quittez, nous avonscertainement pas de savoir qui vous étiez et où nous sommes censés envoyer notre réponse.
De plus, gardez à l'esprit que nous sommes principalement basés en Europe, alors tenez compte des problèmes de fuseau horaire. Si
vous êtes malchanceux plus d'une fois, essayez la liste de diffusion.
Si vous n'avez pas l'application Discord, vous pouvez également utiliser Le client Web de Discord, mais s'il vous plaît, ne partez pas trop
tôt. Assurez-vous simplement de demander sur le #Support canaliser.
Veuillez lire notre Règles de la communauté avant de demander de l'aide sur la liste de diffusion ou le canal Discord.
29
30
deuxieme PARTIE
GUIDE DE PROGRAMMATION
31
32
CHAPITRE
CINQ
BASES DE KIVY
Kivy dépend de nombreuses bibliothèques Python, telles que pygame, gstreamer, PIL, Cairo, etc. Ils ne sont pas tous
nécessaires, mais selon la plate-forme sur laquelle vous travaillez, ils peuvent être difficiles à installer. Pour Windows et MacOS
X, nous fournissons un package portable que vous pouvez simplement décompresser et utiliser.
Consultez l'une de ces pages pour obtenir des instructions d'installation détaillées :
• installation_windows
• installation_osx
• installation_linux
• installation_rpi
Vous pouvez également trouver des instructions pour la version de développement ici :
• montage
• mettre en œuvre son construire() méthode afin qu'elle renvoie un Widget instance (la racine de votre arbre de widgets)
importer kivy
kivy.exiger('1.0.6') # remplacer par votre version actuelle de Kivy !
classer MonApp(Application):
déf construire(soi):
retourner Étiqueter(texte='Bonjour le monde')
33
(suite de la page précédente)
si __Nom__ == '__principale__':
MonApp().Cours()
Vous pouvez l'enregistrer dans un fichier texte, main.py par exemple, et exécutez-le.
Comme vous pouvez le voir ci-dessus, à toutes fins utiles, notre point d'entrée dans notre application est la méthode
run(), et dans notre cas, c'est "MyApp().run()". Nous y reviendrons, mais commençons par la ligne :
Il est nécessaire que la classe de base de votre application hérite de la Application classer. Il est présent dans le
répertoire kivy_installation_dir/kivy/app.py.
Noter: Allez-y et ouvrez ce fichier si vous souhaitez approfondir ce que fait la classe Kivy App. Nous vous
encourageons à ouvrir le code et à le lire. Kivy est basé sur Python et utilise Sphinx pour la documentation, donc
la documentation de chaque classe se trouve dans le fichier réel.
De même à la ligne 5 :
34
à partir de kivy.uix.label importer Étiqueter
Une chose importante à noter ici est la façon dont les packages/classes sont organisés. leuix module est la section qui contient
les éléments de l'interface utilisateur tels que les mises en page et les widgets.
Passons à la ligne 8 :
classer MonApp(Application):
C'est là que nous sommes définir la classe de base de notre application Kivy. Vous ne devriez jamais avoir besoin de changer le nom de
votre applicationMonApp dans cette ligne.
déf construire(soi):
Comme le montre l'image ci-dessus, montrez le boîtier du Cycle de vie de l'application Kivy, c'est la fonction où vous
devez initialiser et retourner votre Widget racine. Voici ce que nous faisons à la ligne 11 :
Ici, nous initialisons une étiquette avec le texte « Hello World » et renvoyons son instance. Cette étiquette sera le widget racine
de cette application.
Noter: Python utilise l'indentation pour désigner les blocs de code, notez donc que dans le code fourni ci-dessus, à la
ligne 11, la définition de la classe et de la fonction se termine.
Passons maintenant à la partie qui fera fonctionner notre application aux lignes 14 et 15 :
si __Nom__ == '__principale__':
MonApp().Cours()
Ici la classe MonApp est initialisé et sa méthode run() est appelée. Cela initialise et démarre notre
application Kivy.
Pour exécuter l'application, suivez les instructions correspondant à votre système d'exploitation :
Pour Windows, Linux, OS X ou le RPi. DuTerminal où vous avez installé Kivy, exécutez simplement :
Python principal.py
Pour Android ou iOS, votre application a besoin de fichiers complémentaires pour pouvoir s'exécuter. VoirCréer un
package pour Android ou voir Créer un package pour IOS pour plus de référence.
Une fenêtre devrait s'ouvrir, affichant une seule étiquette (avec le texte « Hello World ») qui couvre toute la zone de la
fenêtre. C'est tout ce qu'on peut en dire.
35
Traduit de Anglais vers Français - www.onlinedoctranslator.com
Une chose importante à noter ici est la façon dont les packages/classes sont organisés. leuix module est la section qui contient
les éléments de l'interface utilisateur tels que les mises en page et les widgets.
Passons à la ligne 8 :
classer MonApp(Application):
C'est là que nous sommes définir la classe de base de notre application Kivy. Vous ne devriez jamais avoir besoin de changer le nom de
votre applicationMonApp dans cette ligne.
déf construire(soi):
Comme le montre l'image ci-dessus, montrez le boîtier du Cycle de vie de l'application Kivy, c'est la fonction où vous
devez initialiser et retourner votre Widget racine. Voici ce que nous faisons à la ligne 11 :
Ici, nous initialisons une étiquette avec le texte « Hello World » et renvoyons son instance. Cette étiquette sera le widget racine
de cette application.
Noter: Python utilise l'indentation pour désigner les blocs de code, notez donc que dans le code fourni ci-dessus, à la
ligne 11, la définition de la classe et de la fonction se termine.
Passons maintenant à la partie qui fera fonctionner notre application aux lignes 14 et 15 :
si __Nom__ == '__principale__':
MonApp().Cours()
Ici la classe MonApp est initialisé et sa méthode run() est appelée. Cela initialise et démarre notre
application Kivy.
Pour exécuter l'application, suivez les instructions correspondant à votre système d'exploitation :
Pour Windows, Linux, OS X ou le RPi. DuTerminal où vous avez installé Kivy, exécutez simplement :
Python principal.py
Pour Android ou iOS, votre application a besoin de fichiers complémentaires pour pouvoir s'exécuter. VoirCréer un
package pour Android ou voir Créer un package pour IOS pour plus de référence.
Une fenêtre devrait s'ouvrir, affichant une seule étiquette (avec le texte « Hello World ») qui couvre toute la zone de la
fenêtre. C'est tout ce qu'on peut en dire.
35
5.5 Personnaliser l'application
Étendons un peu cette application, disons une simple page de nom d'utilisateur/mot de passe.
classer MonApp(Application):
déf construire(soi):
retourner Écran de connexion()
si __Nom__ == '__principale__':
MonApp().Cours()
36
à partir de kivy.uix.gridlayout importer Disposition de la grille
Cette classe est utilisée comme Base pour notre Root Widget (LoginScreen) défini à la ligne 7 :
A la ligne 9 de la classe LoginScreen, on surcharge la méthode __init__() afin d'ajouter des widgets et de définir
leur comportement :
Il ne faut pas oublier d'appeler super pour implémenter la fonctionnalité de la classe d'origine surchargée. Notez
également qu'il est de bonne pratique de ne pas omettre le**kwargs tout en appelant super, car ils sont parfois
utilisés en interne.
soi.cols = 2
soi.add_widget(Étiqueter(texte='Nom d'utilisateur')) soi.
Nom d'utilisateur = Saisie de texte(multiligne=Faux) soi.
add_widget(soi.Nom d'utilisateur)
soi.add_widget(Étiqueter(texte='le mot de passe'))
soi.le mot de passe = Saisie de texte(le mot de passe=Vrai, multiligne=Faux)
soi.add_widget(soi.le mot de passe)
Nous demandons au GridLayout de gérer ses enfants en deux colonnes et d'ajouter un Étiqueter et un Saisie de texte pour le nom
d'utilisateur et le mot de passe.
L'exécution du code ci-dessus vous donnera une fenêtre qui devrait ressembler à ceci :
Essayez de redimensionner la fenêtre et vous verrez que les widgets à l'écran s'ajustent en fonction de la taille de la
fenêtre sans que vous ayez à faire quoi que ce soit. C'est parce que les widgets utilisent l'indication de taille par défaut.
Le code ci-dessus ne gère pas les entrées de l'utilisateur, ne fait aucune validation ou quoi que ce soit d'autre. Nous
allons approfondir cela etWidget taille et positionnement dans les sections à venir.
37
38
CHAPITRE
SIX
MAÎTRISER L'ENVIRONNEMENT
De nombreuses variables d'environnement sont disponibles pour contrôler l'initialisation et le comportement de Kivy.
Vous pouvez contrôler les répertoires par défaut où se trouvent les fichiers de configuration, les modules et les données kivy.
KIVY_HOME Localisation de la maison Kivy. Ce répertoire est utilisé pour la configuration locale et doit être
dans un endroit inscriptible.
Par défaut :
KIVY_SDL2_PATH Si défini, les bibliothèques SDL2 et les en-têtes de ce chemin sont utilisés lors de la compilation de kivy
au lieu de ceux installés à l'échelle du système. Pour utiliser les mêmes bibliothèques lors de l'exécution d'une application
kivy, ce chemin doit être ajouté au début de la variable d'environnement PATH.
Avertissement: Ce chemin est requis pour la compilation de Kivy. Il n'est pas nécessaire pour l'exécution du
programme.
39
6.2 Paramétrage
KIVY_USE_DEFAULTCONFIG Si ce nom est trouvé dans environ, Kivy ne lira pas la configuration utilisateur
déposer.
KIVY_NO_CONFIG S'il est défini, aucun fichier de configuration ne sera lu ou écrit. Ceci s'applique également à l'utilisateur
répertoire de configuration.
KIVY_NO_ARGS S'il est défini sur l'un des ('true', '1', 'yes'), l'argument passé en ligne de commande ne sera pas
analysé et utilisé par Kivy. C'est-à-dire que vous pouvez créer en toute sécurité un script ou une application avec vos propres
arguments sans avoir besoin du– délimiteur :
KCFG_section_key Si un tel nom d'environnement de format est détecté, il sera mappé à la configuration
objet. Ils ne sont chargés qu'une seule fois lorsquekivy est importé. Le comportement peut être désactivé en
utilisant KIVY_NO_ENV_CONFIG.
KIVY_NO_ENV_CONFIG Si elle est définie, aucune clé d'environnement ne sera mappée à l'objet de configuration. S'il n'est pas réglé,
quelconque KCFG_section_key=valeur sera mappé sur Config.
kivy.core essayez de sélectionner la meilleure implémentation disponible pour votre plate-forme. Pour les tests ou l'installation
personnalisée, vous souhaiterez peut-être restreindre le sélecteur à une implémentation spécifique.
40
KIVY_CAMERA Implémentation à utiliser pour la caméra de lecture
6.4 Métriques
KIVY_METRICS_FONTSCALE
Si elle est définie, la valeur sera utilisée pour Métriques.fontscale.
6.5 Graphiques
Voici une liste des incompatibilités potentielles qui se produisent lorsqu'elles sont définies sur true.
dés
Texas- Lors du blitting à une texture, le format des données (couleur et tampon) doit être le même que celui utilisé
ture lors de la création de la texture. Sur le bureau, la conversion des différentes couleurs est correctement gérée
blit par le pilote, tandis que sur Android, la plupart des appareils ne le font pas. Réf :https://github. com/kivy/
kivy/issues/1600
KIVY_BCM_DISPMANX_ID Modifiez l'affichage par défaut du Raspberry Pi à utiliser. La liste des disponibles
la valeur est accessible dans vc_dispmanx_types.h. La valeur par défaut est 0 :
• 0 : DISPMANX_ID_MAIN_LCD
• 1 : DISPMANX_ID_AUX_LCD
• 2 : DISPMANX_ID_HDMI
• 3 : DISPMANX_ID_SDTV
• 4: DISPMANX_ID_FORCE_LCD
41
• 5 : DISPMANX_ID_FORCE_TV
• 6 : DISPMANX_ID_FORCE_OTHER
KIVY_BCM_DISPMANX_LAYER Modifiez la couche dispmanx par défaut de Raspberry Pi. La valeur par défaut est
0.
Nouveau dans la version 1.10.1.
KIVY_EVENTLOOP Quelle bibliothèque asynchrone doit être utilisée lorsque l'application est exécutée de manière asynchrone
manière. Voirkivy.app par exemple l'utilisation.
'asyncio' : Lorsque l'application est exécutée de manière asynchrone et que la norme bibliothèque asy-
cio package doit être utilisé. La valeur par défaut si elle n'est pas définie.
'trio': Lorsque l'application est exécutée de manière asynchrone et que le trio paquet devrait être
utilisé.
42
CHAPITRE
SEPT
CONFIGURER KIVY
Le fichier de configuration pour kivy est nommé config.ini, et adhère aux INI standard format.
<KIVY_HOME>/configuration.ini
<HOME_DIRECTORY>/.kivy/configuration.ini
<ANDROID_APP_PATH>/.kivy/configuration.ini
<HOME_DIRECTORY>/Documents/.kivy/configuration.ini
Parfois, il est souhaitable de modifier la configuration uniquement pour certaines applications ou lors du test d'une partie
distincte de Kivy, par exemple les fournisseurs d'entrée. Pour créer un fichier de configuration séparé, vous pouvez simplement
utiliser ces commandes :
Configuration.lire(<déposer>)
(suite à la page suivante)
43
(suite de la page précédente)
# définir la configuration
Configuration.écrivez()
Lorsqu'une configuration locale de single .ini file n'est pas suffisant, par exemple lorsque vous voulez avoir un environnement
séparé pour jardin, les journaux kivy et d'autres choses, vous devrez changer le KIVY_HOME variable d'environnement dans
votre application pour obtenir le résultat souhaité :
1. Fenêtres :
définir KIVY_HOME=<dossier>
2. Linux et OSX :
exporter KIVY_HOME=<dossier>
Après le changement de KIVY_HOME, le dossier se comportera exactement de la même manière que le dossier par défaut.kivy/ dossier
mentionné ci-dessus.
44
CHAPITRE
HUIT
APERÇU ARCHITECTURALE
Nous aimerions prendre un moment pour expliquer comment nous avons conçu Kivy du point de vue de l'ingénierie logicielle. C'est la clé
pour comprendre comment tout fonctionne ensemble. Si vous regardez simplement le code, il y a de fortes chances que vous ayez déjà
une idée approximative, mais comme cette approche est certainement intimidante pour la plupart des utilisateurs, cette section explique
les idées de base de l'implémentation plus en détail. Vous pouvez ignorer cette section et vous y référer plus tard, mais nous vous
suggérons au moins de la parcourir pour un aperçu approximatif.
Kivy se compose de plusieurs blocs de construction que nous expliquerons sous peu. Voici un résumé graphique de
l'architecture :
45
8.1 Fournisseurs principaux et fournisseurs d'intrants
Une idée clé pour comprendre les internes de Kivy est celle de la modularité et de l'abstraction. Nous essayons d'abstraire les
tâches de base telles que l'ouverture d'une fenêtre, l'affichage d'images et de texte, la lecture audio, l'obtention d'images à
partir d'un appareil photo, la correction orthographique, etc. Nous appelons cescoeur Tâches. Cela rend l'API à la fois facile à
utiliser et facile à étendre. Plus important encore, cela nous permet d'utiliser - ce que nous appelons - des fournisseurs
spécifiques pour les scénarios respectifs dans lesquels votre application est exécutée. Par exemple, sur OSX, Linux et Windows, il
existe différentes API natives pour les différentes tâches principales. Un morceau de code qui utilise l'une de ces API spécifiques
pour communiquer avec le système d'exploitation d'un côté et avec Kivy de l'autre (agissant comme une couche de
communication intermédiaire) est ce que nous appelons unfournisseur principal. L'avantage d'utiliser des fournisseurs
principaux spécialisés pour chaque plate-forme est que nous pouvons tirer pleinement parti des fonctionnalités exposées par le
système d'exploitation et agir aussi efficacement que possible. Cela donne également le choix aux utilisateurs. De plus, en
utilisant des bibliothèques livrées avec n'importe quelle plate-forme, nous réduisons efficacement la taille de la distribution Kivy
et facilitons l'empaquetage. Cela facilite également le portage de Kivy sur d'autres plates-formes. Le port Android en a
grandement profité.
Nous suivons le même concept avec la gestion des entrées. Un fournisseur d'intrants est un morceau de code qui ajoute la prise en
charge d'un périphérique d'entrée spécifique, tel que les trackpads d'Apple, TUIO ou un émulateur de souris. Si vous devez ajouter la
prise en charge d'un nouveau périphérique d'entrée, vous pouvez simplement fournir une nouvelle classe qui lit vos données d'entrée à
partir de votre périphérique et les transforme en événements de base Kivy.
8.2 Graphiques
L'API graphique de Kivy est notre abstraction d'OpenGL. Au niveau le plus bas, Kivy émet des commandes de dessin accélérées
par matériel à l'aide d'OpenGL. Écrire du code OpenGL peut cependant être un peu déroutant, en particulier pour les nouveaux
arrivants. C'est pourquoi nous fournissons l'API graphique qui vous permet de dessiner des choses en utilisant des métaphores
simples qui n'existent pas en tant que telles dans OpenGL (par exemple Canvas, Rectangle, etc.).
Tous nos widgets eux-mêmes utilisent cette API graphique, qui est implémentée au niveau C pour des raisons de
performances.
Un autre avantage de l'API graphique est sa capacité à optimiser automatiquement les commandes de dessin émises
par votre code. Ceci est particulièrement utile si vous n'êtes pas un expert dans le réglage d'OpenGL. Cela rend votre
code de dessin plus efficace dans de nombreux cas.
Vous pouvez, bien sûr, toujours utiliser des commandes OpenGL brutes si vous préférez. La version que nous ciblons est OpenGL 2.0 ES
(GLES2) sur tous les appareils, donc si vous souhaitez rester compatible multiplateforme, nous vous conseillons de n'utiliser que les
fonctions GLES2.
8.3 Noyau
Le code du package de base fournit des fonctionnalités couramment utilisées, telles que :
Horloge Vous pouvez utiliser l'horloge pour programmer des événements de minuterie. Les minuteries à un coup et périodiques
les minuteries sont prises en charge.
Cacher Si vous avez besoin de mettre en cache quelque chose que vous utilisez souvent, vous pouvez utiliser notre classe pour cela
Langue Kivy Le langage kivy est utilisé pour décrire facilement et efficacement les interfaces utilisateur.
46
Propriétés Ce ne sont pas les propriétés normales que vous connaissez peut-être de python. Ils sont
nos propres classes de propriétés qui lient le code de votre widget à la description de l'interface utilisateur.
Le module UIX contient des widgets et des mises en page couramment utilisés que vous pouvez réutiliser pour créer rapidement une
interface utilisateur.
Widgets Les widgets sont des éléments d'interface utilisateur que vous ajoutez à votre programme pour fournir
une sorte de fonctionnalité. Ils peuvent être visibles ou non. Des exemples seraient un navigateur de
fichiers, des boutons, des curseurs, des listes, etc. Les widgets reçoivent des MotionEvents.
Dispositions Vous utilisez des mises en page pour organiser les widgets. Il est bien entendu possible de calculer votre largeur
obtient vous-même les positions, mais il est souvent plus pratique d'utiliser l'une de nos mises en page prêtes à l'emploi. Des exemples
seraient les dispositions de grille ou les dispositions de boîte. Vous pouvez également imbriquer des mises en page.
8.5 Modules
Si vous avez déjà utilisé un navigateur Web moderne et l'avez personnalisé avec des modules complémentaires, vous connaissez déjà
l'idée de base derrière nos classes de modules. Les modules peuvent être utilisés pour injecter des fonctionnalités dans les programmes
Kivy, même si l'auteur original ne les a pas incluses.
Un exemple serait un module qui montre toujours le FPS de l'application actuelle et un graphique décrivant
le FPS au fil du temps.
Kivy extrait différents types et sources d'entrée tels que les touches, les souris, TUIO ou similaires. Ce que tous ces types d'entrée ont en
commun, c'est que vous pouvez associer une position à l'écran 2D à n'importe quel événement d'entrée individuel. (Il existe d'autres
périphériques d'entrée tels que les accéléromètres pour lesquels vous ne pouvez pas facilement trouver une position 2D pour, par
exemple, une inclinaison de votre périphérique. Ce type d'entrée est géré séparément. Dans ce qui suit, nous décrivons les premiers
types.)
Tous ces types d'entrée sont représentés par des instances de la classe Touch(). (Notez que cela ne fait pas seulement référence
au toucher des doigts, mais aussi à tous les autres types d'entrée. Nous venons de l'appelerToucher pour des raisons de
simplicité. Pensez à quelque chose quitouche l'interface utilisateur ou votre écran.) Une instance tactile, ou un objet, peut être
dans l'un des trois états. Lorsqu'un toucher entre dans l'un de ces états, votre programme est informé que l'événement s'est
produit. Les trois états dans lesquels un toucher peut se trouver sont :
Vers le bas Une touche n'est enfoncée qu'une seule fois, au moment même où elle apparaît pour la première fois.
Se déplacer Un toucher peut être dans cet état pendant une durée potentiellement illimitée. Un toucher n'a pas
être dans cet état au cours de sa vie. Un « Move » se produit chaque fois que la position 2D d'un
toucher change.
En haut Une touche monte au plus une fois, ou jamais. En pratique, vous recevrez presque toujours un
up car personne ne va garder un doigt sur l'écran pour l'éternité, mais ce n'est pas
garanti. Si vous connaissez les sources d'entrée que vos utilisateurs utiliseront, vous
saurez si vous pouvez ou non vous fier à cet état.
47
8.7 Widgets et envoi d'événements
Le terme widget est souvent utilisé dans des contextes de programmation GUI pour décrire une partie du programme avec laquelle
l'utilisateur interagit. Dans Kivy, un widget est un objet qui reçoit des événements d'entrée. Il ne doit pas nécessairement avoir une
représentation visible à l'écran. Tous les widgets sont organisés dans unarbre des widgets (qui est une structure de données
arborescente telle qu'elle est connue dans les cours d'informatique) : Un widget peut avoir n'importe quel nombre de widgets enfants ou
aucun. Il y a exactement unwidget racine en haut de l'arborescence qui n'a pas de widget parent, et tous les autres widgets sont
directement ou indirectement des enfants de ce widget (c'est pourquoi on l'appelle la racine).
Lorsque de nouvelles données d'entrée sont disponibles, Kivy envoie un événement par touche. Le widget racine de
l'arborescence des widgets reçoit d'abord l'événement. Selon l'état du toucher, l'événement on_touch_down,
on_touch_move ou on_touch_up est envoyé (avec le toucher comme argument) au widget racine, ce qui entraîne l'appel
du gestionnaire d'événement on_touch_down, on_touch_move ou on_touch_up correspondant du widget racine.
Chaque widget (ceci inclut le widget racine) de l'arborescence peut choisir de digérer ou de transmettre l'événement. Si
un gestionnaire d'événement renvoie True, cela signifie que l'événement a été digéré et géré correctement. Aucun autre
traitement n'aura lieu avec cet événement. Sinon, le gestionnaire d'événements transmet le widget à ses propres
enfants en appelant l'implémentation de sa superclasse du gestionnaire d'événements respectif. Cela va jusqu'à la
classe Widget de base, qui - dans ses gestionnaires d'événements tactiles - ne fait que transmettre les touches à ses
enfants :
C'est vraiment beaucoup plus facile qu'il n'y paraît au premier abord. Un exemple de la façon dont cela peut être utilisé pour créer
rapidement de belles applications sera donné dans la section suivante.
Souvent, vous voudrez restreindre le région sur l'écran qu'un widget surveille les touches. Vous pouvez utiliser la
méthode collide_point() d'un widget pour y parvenir. Vous lui transmettez simplement la position du toucher et il renvoie
True si le toucher se trouve dans la "zone surveillée" ou False dans le cas contraire. Par défaut, cela vérifie la région
rectangulaire sur l'écran qui est décrite par la position du widget (pour la position ; x et y) et la taille (largeur et hauteur),
mais vous pouvez remplacer ce comportement dans votre propre classe.
48
CHAPITRE
NEUF
ÉVÉNEMENTS ET PROPRIÉTÉS
Les événements sont une partie importante de la programmation Kivy. Cela n'est peut-être pas surprenant pour ceux qui ont de
l'expérience dans le développement d'interfaces graphiques, mais c'est un concept important pour les nouveaux arrivants. Une fois que
vous aurez compris comment fonctionnent les événements et comment vous y lier, vous les verrez partout à Kivy. Ils permettent de créer
facilement le comportement que vous souhaitez dans Kivy.
L'illustration suivante montre comment les événements sont gérés dans le framework Kivy.
Saisir
Opérations non GUI qui
Entrée d'expédition peut être reporté à un
Répartiteur d'événements
Événements fil différent.
Événements personnalisés
Événements de propriété
Événements de fenêtre
Système de fichiers
Post-traitement Réseau
(appuyez deux fois, faites glisser, etc.)
Événements de mouvement
Traiter
IHM graphique
Autre
Boucler
49
9.1 Présentation du répartiteur d'événements
L'une des classes de base les plus importantes du framework est la Répartiteur d'événements classer. Cette classe vous
permet d'enregistrer des types d'événements et de les envoyer aux parties intéressées (généralement d'autres répartiteurs
d'événements). leWidget, Animation et Horloge les classes sont des exemples de répartiteurs d'événements.
Les objets EventDispatcher dépendent de la boucle principale pour générer et gérer les événements.
Comme indiqué dans l'illustration ci-dessus, Kivy a un boucle principale. Cette boucle s'exécute pendant toute la durée
de vie de l'application et ne se ferme qu'en quittant l'application.
À l'intérieur de la boucle, à chaque itération, des événements sont générés à partir de l'entrée de l'utilisateur, de capteurs matériels ou de
quelques autres sources, et les images sont restituées à l'écran.
Votre application spécifiera des rappels (nous y reviendrons plus tard), qui sont appelés par la boucle principale. Si un rappel
prend trop de temps ou ne se ferme pas du tout, la boucle principale est rompue et votre application ne fonctionne plus
correctement.
Dans les applications Kivy, vous devez éviter les boucles longues/infinies ou le sommeil. Par exemple, le code suivant fait les
deux :
Lorsque vous exécutez cela, le programme ne quittera jamais votre boucle, empêchant Kivy de faire toutes les autres choses qui
doivent être faites. En conséquence, tout ce que vous verrez est une fenêtre noire avec laquelle vous ne pourrez pas interagir.
Au lieu de cela, vous devez « planifier » votreanimer_quelquechose() fonction à appeler à plusieurs reprises.
Vous pouvez appeler une fonction ou une méthode toutes les X fois par seconde en utilisant schedule_interval(). Voici un
exemple d'appel d'une fonction nommée my_callback 30 fois par seconde :
déf mon_rappel(dt):
imprimer(« Mon rappel est appelé », dt)
un événement = Horloge.horaire_intervalle(mon_rappel, 1 / 30.)
Vous avez plusieurs façons de déprogrammer un événement déjà programmé. L'un consiste à utiliserAnnuler() ou
déprogrammer() :
un événement.Annuler()
ou:
Horloge.imprévu(un événement)
Alternativement, vous pouvez renvoyer False dans votre rappel, et votre événement sera automatiquement déprogrammé :
=0
compter
déf mon_rappel(dt):
global compter
compter +=1
(suite à la page suivante)
50
(suite de la page précédente)
si compter == dix:
imprimer('Dernier appel de mon rappel, bye bye !') renvoie
Faux
imprimer(« Mon rappel est appelé »)
Horloge.horaire_intervalle(mon_rappel, 1 / 30.)
Utilisant schedule_once(), vous pouvez appeler une fonction "plus tard", comme dans l'image suivante, ou dans X secondes :
déf mon_rappel(dt):
imprimer('Mon rappel est appelé !')
Horloge.horaire_une fois(mon_rappel, 1)
Cela appellera mon_rappel en une seconde. Le deuxième argument est le temps d'attente avant d'appeler la
fonction, en secondes. Cependant, vous pouvez obtenir d'autres résultats avec des valeurs spéciales pour le
deuxième argument :
Le -1 est principalement utilisé lorsque vous êtes déjà dans un événement planifié et si vous souhaitez planifier un appel AVANT
que la prochaine image ne se produise.
Une deuxième méthode pour répéter un appel de fonction consiste à programmer d'abord un rappel une fois avec
schedule_once(), et un deuxième appel à cette fonction à l'intérieur du rappel lui-même :
déf mon_rappel(dt):
imprimer('Mon rappel est appelé !')
Horloge.horaire_une fois(mon_rappel, 1)
Horloge.horaire_une fois(mon_rappel, 1)
Alors que la boucle principale essaiera de respecter l'horaire tel que demandé, il existe une certaine incertitude quant au
moment exact où un rappel programmé sera appelé. Parfois, un autre rappel ou une autre tâche dans l'application
prendra plus de temps que prévu et le timing peut donc être un peu décalé.
Dans cette dernière solution au problème de rappel répétitif, l'itération suivante sera appelée au moins une
seconde après la fin de la dernière itération. Avecschedule_interval() cependant, le rappel est appelé toutes les
secondes.
Parfois, vous souhaiterez peut-être programmer une fonction pour qu'elle ne soit appelée qu'une seule fois pour la trame suivante, évitant ainsi les
appels en double. Vous pourriez être tenté d'y parvenir comme ceci :
51
Cette façon de programmer un déclencheur est coûteuse, car vous appellerez toujours unschedule, même si l'événement est
déjà terminé. De plus, un nouvel événement est créé à chaque fois. Utilisez plutôt un déclencheur :
gâchette = Horloge.create_trigger(mon_rappel)
# plus tard
gâchette()
Chaque fois que vous appelez trigger(), il programmera un seul appel de votre rappel. S'il était déjà programmé, il ne
sera pas reprogrammé.
• Événement de propriété : si votre widget change de position ou de taille, un événement est déclenché.
• Événement défini par le widget : par exemple, un événement sera déclenché pour un bouton lorsqu'il est enfoncé ou relâché.
Pour une discussion sur la façon dont les événements tactiles de widget sont gérés et propagés, veuillez vous référer à la Widget touch
événement bouillonnant section.
Pour créer un répartiteur d'événements avec des événements personnalisés, vous devez enregistrer le nom de l'événement
dans la classe, puis créer une méthode du même nom.
Pour utiliser des événements, vous devez leur lier des rappels. Lorsque l'événement est distribué, vos rappels seront
appelés avec les paramètres relatifs à cet événement spécifique.
Un rappel peut être n'importe quel appel python, mais vous devez vous assurer qu'il accepte les arguments émis par l'événement. Pour
cela, il est généralement plus sûr d'accepter le*arguments argument, qui attrapera tous les arguments dans le arguments liste.
Exemple:
52
déf mon_rappel(valeur, *arguments):
imprimer(« Bonjour, j'ai un événement ! », arguments)
ev = MyEventDispatcher() ev.lier(
on_test=mon_rappel) ev.faire quelque
chose('test')
Veuillez vous référer au kivy.event.EventDispatcher.bind() documentation de la méthode pour plus d'exemples sur la
façon d'attacher des rappels.
Les propriétés sont un excellent moyen de définir des événements et de s'y lier. Essentiellement, ils produisent des événements
tels que lorsqu'un attribut de votre objet change, toutes les propriétés qui font référence à cet attribut sont automatiquement
mises à jour.
Il existe différents types de propriétés pour décrire le type de données que vous souhaitez gérer.
• Propriété de chaîne
• Propriété numérique
• Propriété numérique bornée
• Propriété de l'objet
• Propriété Dict
• Propriété de liste
• OptionPropriété
• AliasPropriété
• Propriété booléenne
• ReferenceListProperty
Pour déclarer des propriétés, vous devez les déclarer au niveau de la classe. La classe fera ensuite le travail pour
instancier les vrais attributs lorsque votre objet sera créé. Ces propriétés ne sont pas des attributs : ce sont des
mécanismes de création d'événements basés sur vos attributs :
classer MonWidget(Widget):
Lors de la substitution __init__, toujours J'accepte **kwargs et utilise super() appeler le parent __init__ méthode, en
passant votre instance de classe :
53
9.8 Envoi d'un événement Propriété
Les propriétés Kivy, par défaut, fournissent un on_<nom_propriété> un événement. Cet événement est appelé lorsque la valeur
de la propriété est modifiée.
Noter: Si la nouvelle valeur de la propriété est égale à la valeur actuelle, alors le on_<nom_propriété> l'événement ne
sera pas appelé.
Nous définissons le pressé Propriété de type Propriété de liste, en lui donnant une valeur par défaut de [0, 0]. A partir
de ce point, leon_pressed event sera appelé chaque fois que la valeur de cette propriété est modifiée.
A la ligne 5 :
Nous supplantons le on_touch_down() méthode de la classe Widget. Ici, nous vérifions la collision du toucher avec
notre widget.
Si le toucher tombe à l'intérieur de notre widget, nous modifions la valeur de pressé à touch.pos et renvoie True,
indiquant que nous avons consommé le toucher et que nous ne voulons plus qu'il se propage.
Enfin, si le toucher tombe en dehors de notre widget, nous appelons l'événement d'origine en utilisant super(. . . ) et renvoie le résultat.
Cela permet à la propagation de l'événement tactile de se poursuivre comme elle se serait normalement produite.
Enfin à la ligne 11 :
Nous définissons un on_pressed fonction qui sera appelée par la propriété chaque fois que la valeur de la propriété est
modifiée.
Noter: Cette on_<prop_name> event est appelé dans la classe où la propriété est définie. Pour surveiller/observer toute
modification apportée à une propriété en dehors de la classe où elle est définie, vous devez vous lier à la
54
propriété comme indiqué ci-dessous.
Comment surveiller les modifications apportées à une propriété lorsque vous n'avez accès qu'à une instance de widget ? Vouslier à la
propriété :
votre_instance_widget.lier(nom de la propriété=nom_fonction)
1 classer RacineWidget(BoxLayout):
2
Si vous exécutez le code tel quel, vous remarquerez deux instructions print dans la console. Un duon_pressed
événement qui est appelé à l'intérieur du Btn personnalisé classe et un autre de la btn_pressed fonction que nous lions
au changement de propriété.
La raison pour laquelle les deux fonctions sont appelées est simple. Lier ne veut pas dire écraser. Avoir ces deux
fonctions est redondant et vous ne devez généralement utiliser qu'une des méthodes d'écoute/réaction aux
changements de propriété.
Vous devez également prendre note des paramètres qui sont passés au on_<nom_propriété> événement ou la
fonction liée à la propriété.
Le premier paramètre est soi, qui est l'instance de la classe où cette fonction est définie. Vous pouvez utiliser une
fonction en ligne comme suit :
1 cb = Btn personnalisé()
2
6 cb.lier(pressé=_local_func) soi.
sept add_widget(cb)
Voici l'exemple complet, dérivé des extraits ci-dessus, que vous pouvez utiliser pour copier et coller dans un
éditeur pour expérimenter.
55
(suite de la page précédente)
13 cb.lier(pressé=soi.btn_pressed) soi.
14 add_widget(cb)
15 soi.add_widget(Bouton(texte='btn 2'))
16
36
37 déf construire(soi):
38 retourner RacineWidget()
39
40
41 si __Nom__ == '__principale__':
42 Application de test().Cours()
56
Notre CustomBtn n'a pas de représentation visuelle et apparaît donc en noir. Vous pouvez toucher/cliquer sur la zone
noire pour voir la sortie sur votre console.
Lors de la définition d'un AliasPropriété, vous définissez normalement vous-même une fonction getter et setter. Ici, il
vous appartient de définir quand les fonctions getter et setter sont appelées à l'aide de lalier argument.
dix '''
Ici curseur_pos est un AliasPropriété qui utilise le getter _get_cursor_pos avec le setter partie définie sur Aucun, ce qui implique
qu'il s'agit d'une propriété en lecture seule.
L'argument bind à la fin définit que on_cursor_pos l'événement est distribué lorsque l'une des propriétés utilisées dans
le lier = changement d'argumentation.
57
58
CHAPITRE
DIX
Kivy est capable de gérer la plupart des types de saisie : souris, écran tactile, accéléromètre, gyroscope, etc. Il
gère les protocoles multitouch natifs sur les plateformes suivantes : Tuio, WM_Touch, MacMultitouchSupport, MT
Protocol A/B et Android.
Fournisseurs d'intrants -> Événement de mouvement -> Post-traitement -> Envoi à la fenêtre
La classe de tous les événements d'entrée est la Événement de mouvement. Il génère 2 types d'événements :
• Événements tactiles : un événement de mouvement qui contient au moins une position X et Y. Tous les événements tactiles sont
répartis dans l'arborescence des widgets.
• Événements sans contact : tout le reste. Par exemple, l'accéléromètre est un événement continu, sans position. Il ne
démarre ni ne s'arrête jamais. Ces événements ne sont pas distribués dans l'arborescence des widgets.
Un événement de mouvement est généré par un Fournisseur d'entrée. Un fournisseur d'entrée est chargé de lire l'événement
d'entrée à partir du système d'exploitation, du réseau ou même d'une autre application. Plusieurs fournisseurs d'intrants
existent, tels que :
• et beaucoup plus!
Lorsque vous écrivez une application, vous n'avez pas besoin de créer un fournisseur d'entrée. Kivy essaie de détecter
automatiquement le matériel disponible. Cependant, si vous souhaitez prendre en charge du matériel personnalisé, vous devrez
configurer kivy pour le faire fonctionner.
Avant que l'événement de mouvement nouvellement créé ne soit transmis à l'utilisateur, Kivy applique un post-traitement à l'entrée.
Chaque événement de mouvement est analysé pour détecter et corriger les entrées défectueuses, ainsi que pour faire des
interprétations significatives telles que :
• Rendre les événements plus précis lorsque le matériel n'est pas précis
• Réduction du nombre d'événements générés si le matériel tactile natif envoie des événements avec presque
la même position
Après le traitement, l'événement de mouvement est envoyé à la fenêtre. Comme expliqué précédemment, tous les événements ne sont
pas distribués à l'ensemble de l'arborescence des widgets : la fenêtre les filtre. Pour un événement donné :
59
• s'il ne s'agit que d'un événement de mouvement, il sera envoyé à on_motion()
• s'il s'agit d'un événement tactile, la position (x,y) du toucher (plage 0-1) sera mise à l'échelle de la taille de la fenêtre
(largeur/hauteur) et envoyée à :
– on_touch_down()
– on_touch_move()
– on_touch_up()
En fonction de votre matériel et des fournisseurs d'entrées utilisés, plus d'informations peuvent être mises à votre disposition.
Par exemple, une entrée tactile a une position (x,y), mais peut également avoir des informations sur la pression, la taille du blob,
un vecteur d'accélération, etc.
Un profil est une chaîne qui indique les fonctionnalités disponibles dans l'événement de mouvement. Imaginons que
vous soyez dans unon_touch_move méthode:
['pos', 'angle']
Pour le 'pos' profil, les propriétés position, x, et oui sera disponible. Avec le 'angle' profil, la propriété une sera
disponible. Comme nous l'avons dit, pour les événements tactiles 'pos' est un profil obligatoire, mais pas 'angle'.
Vous pouvez prolonger votre interaction en vérifiant si le 'angle' le profil existe :
Vous pouvez trouver une liste des profils disponibles dans le événement de mouvement Documentation.
Un événement tactile est un événement spécialisé Événement de mouvement où la propriété is_touch évalue à True. Pour
tous les événements tactiles, vous disposez automatiquement des positions X et Y, adaptées à la largeur et à la hauteur de la
fenêtre. En d'autres termes, tous les événements tactiles ont le 'pos' profil.
60
10.3.1 Principes de base des événements tactiles
Par défaut, les événements tactiles sont envoyés à tous les widgets actuellement affichés. Cela signifie que les widgets reçoivent
l'événement tactile, qu'il se produise ou non dans leur zone physique.
Cela peut être contre-intuitif si vous avez de l'expérience avec d'autres boîtes à outils GUI. Ceux-ci divisent généralement l'écran
en zones géométriques et n'envoient des événements tactiles ou de souris au widget que si la coordonnée se trouve dans la
zone des widgets.
Cette exigence devient très restrictive lorsque l'on travaille avec la saisie tactile. Les balayages, les
pincements et les appuis longs peuvent provenir de l'extérieur du widget qui veut les connaître et y réagir.
Afin de fournir une flexibilité maximale, Kivy distribue les événements à tous les widgets et leur permet de décider comment y
réagir. Si vous souhaitez uniquement répondre aux événements tactiles à l'intérieur du widget, il vous suffit de cocher :
10.3.2 Coordonnées
Vous devez vous occuper de la transformation matricielle dans votre toucher dès que vous utilisez un widget avec
transformation matricielle. Certains widgets tels queDispersion ont leur propre transformation matricielle, ce qui signifie que le
toucher doit être multiplié par la matrice de dispersion pour pouvoir distribuer correctement les positions tactiles aux enfants
du Scatter.
Vous devez utiliser l'un d'eux pour mettre correctement les coordonnées à l'échelle du contexte. Regardons l'implémentation du scatter :
# quel que soit le résultat, n'oubliez pas de faire éclater votre transformation
# après l'appel, donc la coordonnée sera de retour dans l'espace parent toucher.
pop()
61
10.3.3 Formes tactiles
Si le toucher a une forme, cela sera reflété dans la propriété 'shape'. À l'heure actuelle, seul unFormeRect peut être
exposé :
Un double tap est l'action de tapoter deux fois dans un temps et une distance. Il est calculé par le module de post-
traitement doubletap. Vous pouvez tester si le toucher actuel est celui d'un double tap ou non :
Un triple tap est l'action de tapoter trois fois dans un temps et une distance. Il est calculé par le module de post-
traitement tripletap. Vous pouvez tester si le toucher actuel est l'un d'un triple tap ou non :
Il est possible pour le widget parent d'envoyer un événement tactile à un widget enfant depuis l'intérieur
on_touch_down, mais pas de on_touch_move ou on_touch_up. Cela peut se produire dans certains scénarios, comme
lorsqu'un mouvement tactile est en dehors de la zone de délimitation du parent, de sorte que le parent décide de ne pas
informer ses enfants du mouvement.
Mais vous voudrez peut-être faire quelque chose dans on_touch_up. Disons que vous avez commencé quelque chose dans le
on_touch_down événement, comme jouer un son, et vous aimeriez finir les choses sur le on_touch_up un événement.
Saisir est ce dont vous avez besoin.
Lorsque vous saisissez une touche, vous recevrez toujours l'événement de déplacement et de montée. Mais il y a certaines
limites à la saisie :
• Vous recevrez l'événement au moins deux fois : une fois de votre parent (l'événement normal), et une
fois de la fenêtre (saisir).
62
• Vous pouvez recevoir un événement avec un toucher saisi, mais pas de vous : cela peut être dû au fait que le parent
a envoyé le toucher à ses enfants alors qu'il était dans l'état saisi.
# et acceptez le toucher.
retourner vrai
# n'oubliez pas de vous défaire, ou vous pourriez avoir des effets secondaires
toucher.dégager(soi)
# et accepter le dernier up
retourner vrai
Afin de voir comment les événements tactiles sont contrôlés et propagés entre les widgets, veuillez vous référer à la Widget
touch événement bouillonnant section.
Une entrée de joystick représente les valeurs brutes reçues directement des contrôleurs physiques ou virtuels via le fournisseur
SDL2 via ces événements :
• SDL_JOYAXISMOTION
• SDL_JOYHATMOTION
• SDL_JOYBALLMOTION
• SDL_JOYBUTTONDOWN
• SDL_JOYBUTTONUP
Chaque événement de mouvement a une valeur minimale, maximale et par défaut qui peut atteindre :
63
Les événements de bouton, d'autre part, ne représentent fondamentalement qu'un état de chaque bouton, c'est-à-dire en haut et vers le bas, par conséquent,
• on_joy_button_up
• on_joy_button_down
Contrairement aux événements tactiles, les événements de joystick sont envoyés directement à la fenêtre, ce qui signifie qu'il n'y a qu'une
seule valeur transmise pour, par exemple, un axe spécifié, pas plusieurs. Cela rend les choses plus difficiles si vous souhaitez séparer les
entrées de différents widgets, mais pas impossible. Vous pouvez utiliserExemple de dropfile multiple comme inspiration.
Pour obtenir un événement joystick, vous devez d'abord lier une fonction à l'événement Window joystick comme ceci :
Fenêtre.lier(on_joy_axis=soi.on_joy_axis)
Ensuite, vous devez récupérer les paramètres spécifiés dans Fenêtre pour chaque événement que vous utilisez, par exemple :
Une variable collant est l'identifiant d'un contrôleur qui a envoyé la valeur, axe est l'identifiant d'un axe auquel appartient la
valeur.
Kivy devrait pouvoir récupérer les entrées de n'importe quel appareil spécifié comme manette de jeu, manette ou
essentiellement tout autre type de contrôleur de jeu reconnu par le fournisseur SDL2. Pour faciliter les choses, voici les
dispositions de certains contrôleurs courants ainsi que les identifiants de chaque partie.
64
Xbox 360
# identifiant # identifiant
1 axe 1 2 axe 0
3 chapeau Y 4 chapeau X
5 axe 4 6 axe 3
sept axe 2 8 axe 5
9 bouton 4 dix bouton 5
X bouton 2 Oui bouton 3
UNE bouton 0 B bouton 1
retour bouton 6 début bouton 7
centre bouton 10
La plupart du temps, vous voudriez déboguer votre application avec plusieurs contrôleurs ou la tester par rapport à _autres_
types de contrôleurs (par exemple, différentes marques). Comme alternative, vous pouvez utiliser certains des émulateurs de
contrôleur disponibles, tels quevJoy.
65
66
CHAPITRE
ONZE
WIDGETS
UNE Widget est le bloc de construction de base des interfaces graphiques dans Kivy. Il fournit unToile qui peut être
utilisé pour dessiner à l'écran. Il reçoit les événements et y réagit. Pour une explication détaillée de laWidget classe,
consultez la documentation du module.
Les widgets à Kivy sont organisés en arbres. Votre candidature a unwidget racine, qui a généralement enfants
qui peut avoir enfants de leur propre. Les enfants d'un widget sont représentés par leenfants attribut, un Kivy
Propriété de liste.
L'arborescence des widgets peut être manipulée avec les méthodes suivantes :
Le bouton est ajouté à layout : la propriété parent du bouton sera définie sur layout ; la mise en page aura le
bouton ajouté à sa liste d'enfants. Pour supprimer le bouton de la mise en page :
disposition.supprimer_widget(bouton)
Avec la suppression, la propriété parent du bouton sera définie sur Aucun et la mise en page aura le bouton supprimé
de sa liste d'enfants.
Si vous souhaitez effacer tous les enfants à l'intérieur d'un widget, utilisez clear_widgets() méthode:
disposition.clear_widgets()
Avertissement: Ne manipulez jamais vous-même la liste des enfants, à moins que vous ne sachiez vraiment ce que vous
faites. L'arbre des widgets est associé à un arbre graphique. Par exemple, si vous ajoutez un widget dans le
67
liste des enfants sans ajouter son canevas à l'arborescence graphique, le widget sera un enfant, oui, mais rien
ne sera dessiné à l'écran. De plus, vous pourriez avoir des problèmes lors d'appels ultérieurs de add_widget,
remove_widget et clear_widgets.
L'instance de la classe Widget enfants La propriété list contient tous les enfants. Vous pouvez facilement parcourir
l'arbre en faisant :
racine = BoxLayout()
# . . . ajouter des widgets à la racine ...
pour enfant dans racine.enfants:
imprimer(enfant)
Cependant, cela doit être utilisé avec précaution. Si vous avez l'intention de modifier la liste des enfants avec l'une des méthodes
indiquées dans la section précédente, vous devez utiliser une copie de la liste comme celle-ci :
Les widgets n'influencent pas la taille/la position de leurs enfants par défaut. leposition l'attribut est la position absolue dans les
coordonnées de l'écran (à moins que vous n'utilisiez le Disposition relative. Plus à ce sujet plus tard) etTaille, est une taille
absolue.
L'ordre de dessin des widgets est basé sur la position du widget dans l'arborescence des widgets. leadd_widget méthode prend
un indice paramètre qui peut être utilisé pour spécifier sa position dans l'arborescence des widgets :
racine.add_widget(widget, indice)
Les widgets les moins indexés seront dessinés au-dessus de ceux avec un index plus élevé. Gardez à l'esprit que la valeur par
défaut pourindice est 0, donc les widgets ajoutés plus tard sont dessinés au-dessus des autres, sauf indication contraire.
disposition est un type spécial de widget qui contrôle la taille et la position de ses enfants. Il existe différents types de
mises en page, permettant une organisation automatique différente de leurs enfants. Utilisation des mises en page
size_hint et pos_hint propriétés pour déterminer la Taille et position de leur enfants.
BoxLayout: organise les widgets de manière adjacente (soit verticalement, soit horizontalement), pour remplir tout l'espace. La
propriété size_hint des enfants peut être utilisée pour modifier les proportions autorisées pour chaque enfant ou définir une
taille fixe pour certains d'entre eux.
68
69
Disposition de la grille: organise les widgets dans une grille. Vous devez spécifier au moins une dimension de la grille pour que
kivy puisse calculer la taille des éléments et comment les organiser.
StackLayout: organise les widgets les uns à côté des autres, mais avec une taille définie dans l'une des
dimensions, sans essayer de les faire tenir dans tout l'espace. Ceci est utile pour afficher les enfants de la même
taille prédéfinie.
AncreLayout: Une mise en page simple ne se souciant que des positions des enfants. Il permet de placer les enfants à une
position relative à une bordure de la mise en page.size_hint n'est pas honoré.
Mise en page flottante: permet de placer des enfants avec des emplacements et des tailles arbitraires, absolus ou relatifs à la taille de la
mise en page. Par défaut size_hint (1, 1) fera que chaque enfant aura la même taille que l'ensemble de la mise en page, vous voudrez
donc probablement modifier cette valeur si vous avez plus d'un enfant. Vous pouvez définir size_hint sur (Aucun, Aucun) pour utiliser la
taille absolue avecTaille. Ce widget honorepos_hint aussi, qui en tant que position de réglage de dict par rapport à la position de mise en
page.
Disposition relative: se comporte comme FloatLayout, sauf que les positions des enfants sont relatives à la position de la disposition, pas
à l'écran.
Examinez la documentation des mises en page individuelles pour une compréhension plus approfondie.
70
size_hint et pos_hint:
• floatlayout
• mise en page
• disposition de la grille
• disposition de la pile
• Disposition relative
• disposition d'ancrage
size_hint est un ReferenceListProperty de size_hint_x et size_hint_y. Il accepte les valeurs de0 à 1 ou Rien et
par défaut à (1, 1). Cela signifie que si le widget est dans une mise en page, la mise en page lui allouera autant de
place que possible dans les deux sens (par rapport à la taille des mises en page).
Réglage size_hint à (0.5, 0.8), par exemple, fera du widget 50% la largeur et 80% la hauteur de la taille disponible
pour le Widget à l'intérieur d'un disposition.
BoxLayout:
Bouton:
texte: 'Bouton 1'
# size_hint par défaut est 1, 1, nous n'avons pas besoin de le spécifier explicitement
# cependant c'est fourni ici pour clarifier les choses size_hint: 1
,1
Chargez maintenant le catalogue kivy en tapant ce qui suit, mais en remplaçant $KIVYDIR par le répertoire
de votre installation (découvrable via os.path.dirname(kivy.__file__)):
cd $KIVYDIR/examples/demo/kivycatalog python
main.py
Une nouvelle fenêtre apparaîtra. Cliquez dans la zone en dessous du 'Bienvenue'Fileur sur la gauche et
remplacez le texte par votre code kv ci-dessus.
71
Comme vous pouvez le voir sur l'image ci-dessus, le Bouton occupe 100% de la mise en page Taille.
72
Vous pouvez voir ici que, bien que nous précisions size_hint_x et size_hint_y les deux à 0,5, seulement
size_hint_y semble honoré. C'est parce quemise en page contrôle le size_hint_y lorsque orientation est
verticale et size_hint_x lorsque orientation est "horizontal". La taille de la dimension contrôlée est calculée
en fonction du nombre total. deenfants dans le mise en page. Dans cet exemple, un enfant asize_hint_y
contrôlé (.5/.5 = 1). Ainsi, le widget prend 100% de la hauteur de la mise en page parent.
73
mise en page par sa nature même divise l'espace disponible entre ses enfants également. Dans notre exemple,
la proportion est de 50-50, car nous avons deuxenfants. Utilisons size_hint sur l'un des enfants et voyons les
résultats.
74
Si un enfant spécifie size_hint, cela spécifie combien d’espace le Widget va prendre de la taille qui lui
_hint
est donnée par la boxlayout. Dans notre exemple, le premier bouton indique . 5 pour size _x.
L’espace pour le widget est calculé comme ceci :
divisé par
Indice de taille du premier enfant
du
size_hint premier enfant + size_hint du deuxième enfant + ...n(aucun enfant)
.5/(.5+1) = .333...
Le reste de la largeur du BoxLayout est réparti entre les autres enfants. Dans notre exemple,
cela signifie que le deuxième bouton occupe 66,66% de la largeur de la mise en page.
_
Expérimentez avec size hint pour être à l’aise avec elle.
Si vous voulez contrôler la taille absolue d’un Widget, vous pouvez définir size_hint_x/size_hint_y
ou les deux à None pour que les attributs width et ou height du widget soient honorés.
_ _hint
pos hint est un dict, qui se vide par défaut. Comme pour size , les mises en page honorent
pos_hint différemment, mais généralement vous pouvez ajouter des valeurs à n’importe lequel des
_x, center Widget
attributs pos (x, y, right, top, center _y) pour que le soit positionné par rapport
à son parent.
_
Expérimentons le code suivant dans kivycatalog pour comprendre pos hint visuellement :
FloatLayout :
Bouton :
texte : « We Will »
pos : 100, 100
_
size hint : . 2, . 4
Bouton :
(suite à la page suivante)
75
(suite de la page précédente)
text: "Wee Wiill"
pos : 200, 200
_
size hint : . 4, . 2
Bouton :
texte : « ROCK YOU! »
_
pos hint : {'x' : . 3, 'y' : . 6}
_
size hint : . 5, . 2
Cela nous donne :
_hint
Comme avec size , vous devriez expérimenter avec pos_hint pour comprendre l’effet qu’il a
sur les positions du widget.
Une des questions fréquemment posées sur les mises en page est la suivante :
De par leur nature, les mises en page n’ont pas de représentation visuelle : elles n’ont pas
d’instructions sur toile par défaut. Cependant, vous pouvez facilement ajouter des instructions canvas
à une instance de mise en page, comme avec l’ajout d’un fond coloré :
En Python :
76
à partir de kivy.graphics importer couleur, rectangle
instance.canvas.before
avec layout_ :
Couleur(0, 1, 0, 1) # vert; gamme de couleurs de 0-1 au lieu de 0-255 self.rect =
instance.size,
Rectangle(size=layout_
_
pos=layout instance.pos)
Malheureusement, cela ne dessinera qu’un rectangle à la position et à la taille initiales de la mise en
page. Pour s’assurer que le rect est dessiné à l’intérieur de la mise en page, lorsque la taille de la
mise en page / pos change, nous devons écouter les changements et mettre à jour la taille des
rectangles et pos. Nous pouvons procéder comme suit :
instance.canvas.before
avec layout_ :
Couleur(0, 1, 0, 1) # vert; gamme de couleurs de 0-1 au lieu de 0-255 self.rect =
instance.size,
Rectangle(size=layout_
_
pos=layout instance.pos)
_
def update rect(instance, value) :
instance.rect.pos = instance.pos
instance.rect.size = instance.size
FloatLayout :
avant :
Couleur :
rgba : 0, 1, 0, 1
Rectangle :
# self ici se réfère au widget i.e FloatLayout pos : self.pos
taille : auto.size
La déclaration kv définit une liaison implicite : les deux dernières lignes kv garantissent que les
valeurs pos et size du rectangle seront mises à jour lorsque le pos du floatlayout change.
Maintenant, nous mettons les fragments ci-dessus dans la coquille de Kivy App.
Méthode Python pur :
classe RootWidget(FloatLayout) :
__ __
def init (self, **kwargs):
# assurez-vous que nous ne surchargeons aucune fonctionnalité
_ __
importante super(RootWidget, self). _init (**kwargs)
# ajoutons un Widget à cette mise en page
_
self.add widget(
Bouton(
(suite à la page suivante)
77
(suite de la page précédente)
text="Hello World",
_
size hint=(.5, .5),
_hint ':
pos ={'center_x . 5, 'center_y' : . 5})
class MainApp(App) :
def build(self) :
self.root = root = RootWidget()
update_rect, pos=self. )
root.bind(size=self._ _update_rect
avec root.canvas.before :
Couleur(0, 1, 0, 1) # vert; gamme de couleurs de 0-1 pas 0-255 self.rect =
Rectangle(size=root.size, pos=root.pos)
racine de retour
_
def update_rect(self, instance, valeur) :
self.rect.pos = instance.pos self.rect.size =
instance.size
_ __ _ __
si _name == ' _main ':
MainApp(). run()
Utilisation de la langue kv :
_
root = Builder.load string('''
FloatLayout :
avant :
Couleur :
rgba : 0, 1, 0, 1
Rectangle :
# self ici se réfère au widget i.e FloatLayout pos : self.pos
taille : auto.size
Bouton :
texte : « Bonjour le monde ! »
_
size hint : . 5, . 5
_hint ':. 5, 'center_y' : . 5}
pos : {'center_x
'''')
class MainApp(App) :
def build(self) :
racine de retour
_ __ _ __
si _name == ' _main ':
MainApp(). run()
78
11.6.1 Ajouter une couleur à l’arrière-plan d’une règle/classe de dispositions
personnalisées
La façon dont nous ajoutons l’arrière-plan à l’instance de la mise en page peut rapidement devenir
lourde si nous avons besoin d’utiliser plusieurs mises en page. Pour vous aider, vous pouvez sous-
classer la mise en page et créer votre propre mise en page qui ajoute un arrière-plan.
Utilisation de Python :
class RootWidget(BoxLayout) :
passer
79
(suite de la page précédente)
avec self.canvas.avant :
Couleur(0, 1, 0, 1) # vert; gamme de couleurs de 0-1 au lieu de 0-
,!255
self.rect = Rectangle(size=self.size, pos=self.pos)
_
self.bind(size=self._update_rect, pos=self. update_rect)
_
def update_rect(self, instance, valeur) :
self.rect.pos = instance.pos self.rect.size =
instance.size
class MainApp(App) :
def build(self) :
root = RootWidget()
c = CustomLayout()
_
root.add widget(c)
_
c.add widget(
AsyncImage(
source="http://www.everythingzoomer.com/wp-content/uploads/
! 2013/01/Monday-joke-289x277.jpg",
_
size hint= (1, .5),
_hint . 5}))
pos ={'center_x':. 5, 'center_y':
_
root.add widget(AsyncImage(source='http://www.stuffistumbledupon.
! com/wp-content/uploads/2012/05/Have-you-seen-this-dog-because-its-,! awesome-
meme-puppy-doggy.jpg'))
c = CustomLayout()
_
c.add widget(
AsyncImage(
source="http://www.stuffistumbledupon.com/wp-content/
,! uploads/2012/04/Get-a-Girlfriend-Meme-empty-wallet.jpg",
_
size hint= (1, .5),
_hint . 5}))
pos ={'center_x':. 5, 'center_y':
_
root.add widget(c)
racine de retour
_ __ _ __
si _name == ' _main ':
MainApp(). run()
Utilisation de la langue kv :
_
Builder.load string('''
<CustomLayout>
avant :
Couleur :
rgba : 0, 1, 0, 1
(suite à la page suivante)
80
(suite de la page précédente)
Rectangle :
pos : self.pos
taille : auto.size
<RootWidget>
CustomLayout :
AsyncImage :
source : 'http://www.everythingzoomer.com/wp-content/uploads/
,!2013/01/monday-joke-289x277.jpg'
_
size hint : 1, . 5
_hint ':. 5, 'center_y' : . 5}
pos : {'center_x
AsyncImage :
source : 'http://www.stuffistumbledupon.com/wp-content/uploads/2012/ ,!05/Have-
you-seen-this-dog-because-its-awesome-meme-puppy-doggy.jpg'
CustomLayout
AsyncImage :
source : 'http://www.stuffistumbledupon.com/wp-content/uploads/
,!2012/04/Get-a-Girlfriend-Meme-empty-wallet.jpg'
_
size hint : 1, . 5
_hint ':. 5, 'center_y' : . 5}
pos : {'center_x
'''')
class RootWidget(BoxLayout) :
passer
class MainApp(App) :
def build(self) :
return RootWidget()
_ __ _ __
si _name == ' _main ':
MainApp(). run()
81
Définir l’arrière-plan dans la classe de mise en page personnalisée, assure qu’il sera utilisé dans
chaque instance de CustomLayout.
Maintenant, pour ajouter une image ou une couleur à l’arrière-plan d’une mise en page Kivy intégrée,
globalement, nous devons outrepasser la règle kv pour la mise en page en question. Envisager
GridLayout :
<GridLayout>
avant :
Couleur :
rgba : 0, 1, 0, 1
BorderImage :
source : '.. /examples/widgets/sequenced_images/data/images/
_white.png’
,!button
pos : self.pos
taille : auto.size
Puis, lorsque nous avons mis ce fragment dans une application Kivy :
_
Builder.load string('''
<GridLayout>
avant :
BorderImage :
# BorderImage se comporte comme le BorderImage CSS
(suite à la page suivante)
82
(suite de la page précédente)
frontière : 10, 10, 10, 10
source : '.. /examples/widgets/sequenced_images/data/images/
_white.png’
,!button
pos : self.pos
taille : auto.size
<RootWidget>
GridLayout :
_
size hint : . 9, . 9
_hint ' : . 5, 'center_y' : . 5}
pos : {'center_x
lignes : 1
Étiquette :
texte : "Je ne souffre pas de démence, je profite de chaque minute
,»
_
text size : self.width-20, self.height-20
valign : 'top'
Étiquette :
texte : "Quand je suis né, j’ai été tellement surpris; Je n’ai pas parlé pendant
un an et demi.
_
text size : self.width-20, self.height-20
valign : 'middle'
halign : 'centre’
Étiquette :
texte : "Un consultant est quelqu’un qui prend un sujet que vous !
_
text size : self.width-20, self.height-20
valign : 'bottom'
halign : 'justifié’
'''')
classe RootWidget(FloatLayout) :
passer
class MainApp(App) :
def build(self) :
return RootWidget()
_ __ _ __
si _name == ' _main ':
MainApp(). run()
83
Comme nous contournons la règle de la classe GridLayout, toute utilisation de cette classe dans
notre application affichera cette image.
Que diriez-vous d’un fond animé?
Vous pouvez définir les instructions de dessin comme Rectangle/BorderImage/Ellipse/. . pour utiliser
une texture particulière :
Rectangle :
texture : référence à une texture
_
Builder.load string('''
<CustomLayout>
avant :
BorderImage :
# BorderImage se comporte comme la bordure CSS
BorderImage : 10, 10, 10, 10
(suite à la page suivante)
84
(suite de la page précédente)
image.texture
texture : self.background_
pos : self.pos
taille : auto.size
<RootWidget>
CustomLayout :
_
size hint : . 9, . 9
_hint ' : . 5, 'center_y' : . 5}
pos : {'center_x
lignes : 1
Étiquette :
texte : "Je ne souffre pas de démence, je profite de chaque minute
,»
_
text size : self.width-20, self.height-20
valign : 'top'
Étiquette :
texte : "Quand je suis né, j’ai été tellement surpris; Je n’ai pas parlé pendant
un an et demi.
_
text size : self.width-20, self.height-20
valign : 'middle'
halign : 'centre’
Étiquette :
texte : "Un consultant est quelqu’un qui prend un sujet que vous !
_
text size : self.width-20, self.height-20
valign : 'bottom'
halign : 'justifié’
'''')
_
anim delay=.1))
classe RootWidget(FloatLayout) :
passer
class MainApp(App) :
def build(self) :
return RootWidget()
_ __ _ __
si _name == ' _main ':
MainApp(). run()
85
_
texture : self.background image.texture
Ceci spécifie que la propriété texture de BorderImage sera mise à jour chaque fois que la propriété
texture de background_image est mise à jour. Nous définissons la propriété background_image à la
ligne 40 :
_
background image = ObjectProperty(...
Cela configure background_image comme une ObjectProperty dans laquelle nous ajoutons un widget
Image. Un widget d’image a une propriété de texture; où vous voyez self.background_image.texture, ceci
définit une référence, texture, à cette propriété. Le widget Image prend en charge l’animation : la texture
de l’image est mise à jour chaque fois que l’animation change, et la texture de l’instruction BorderImage est
mise à jour dans le processus.
Vous pouvez également simplement blit données personnalisées à la texture. Pour plus de détails,
consultez la documentation de Texture.
Oui! C’est assez amusant de voir à quel point le processus peut être extensible.
L’unité par défaut de Kivy pour la longueur est le pixel, toutes les tailles et positions y sont exprimées
par défaut. Vous pouvez les exprimer dans d’autres unités, ce qui est utile pour obtenir une meilleure
cohérence entre les appareils (ils sont convertis en taille en pixels automatiquement).
Les unités disponibles sont pt, mm, cm, inch, dp et sp. Vous pouvez en apprendre davantage sur
leur utilisation dans la documentation des métriques.
Vous pouvez également expérimenter l’utilisation de l’écran pour simuler différents écrans
d’appareils pour votre application.
Si votre application est composée de divers écrans, vous voulez probablement un moyen facile de
naviguer d’un écran à l’autre. Heureusement, il y a la classe ScreenManager, qui vous permet de
définir des écrans séparément, et de définir la base de TransitionBase de l’un à l’autre.
86
CHAPITRE
DOUZE
GRAPHIQUES
Une représentation graphique Widgets est rendue à l’aide d’une toile, que vous pouvez voir à la fois
comme un tableau à dessin illimité ou comme un ensemble d’instructions de dessin. Il y a de
nombreuses instructions que vous pouvez appliquer (ajouter) à votre toile, mais il y a deux variations
principales :
• instructions contextuelles
• instructions sur le vertex
Les instructions contextuelles ne dessinent rien, mais elles modifient les résultats des instructions du
vertex.
Les sollicitations peuvent contenir deux sous-ensembles d’instructions. Ils sont la toile.avant et la
toile. après les groupes d’instruction. Les instructions de ces groupes seront exécutées
respectivement avant et après le groupe canvas. Cela signifie qu’ils apparaîtront sous (être exécutés
avant) et au-dessus (être exécutés après). Ces groupes ne sont pas créés tant que l’utilisateur n’y
accède pas.
Pour ajouter une instruction canvas à un widget, vous utilisez le contexte canvas :
classe MyWidget(Widget) :
__ __
def init (self, **kwargs):
_ __
(*kwargs)
super(MyWidget, self). _init
avec self.canvas :
# ajouter vos instructions pour la toile principale ici
avec self.canvas.avant :
# vous pouvez l’utiliser pour ajouter des instructions rendues avant
avec self.canvas.after :
# vous pouvez l’utiliser pour ajouter des instructions rendues après
Les instructions de contexte manipulent le contexte opengl. Vous pouvez faire pivoter, traduire et
mettre à l’échelle votre toile. Vous pouvez également fixer une texture ou changer la couleur du
dessin. Celui-ci est le plus couramment utilisé, mais d’autres sont vraiment utiles aussi :
avec self.canvas.avant :
Couleur(1, 0, .4, mode='rgb')
87
12.3 Instructions de dessin
Les instructions de dessin vont de très simples, comme tracer une ligne ou un polygone, à plus
complexes, comme des maillages ou des courbes béziers :
avec self.canvas :
# tracer une ligne en utilisant la couleur par
défaut Line(points=(x1, y1, x2, y2, x3, y3))
Parfois, vous voulez mettre à jour ou supprimer les instructions que vous avez ajoutées à une toile.
Cela peut se faire de différentes façons selon vos besoins :
Vous pouvez conserver une référence à vos instructions et les mettre à jour :
classe MyWidget(Widget) :
__ __
def init (self, **kwargs):
_ __
(*kwargs)
super(MyWidget, self). _init
avec self.canvas :
self.rect = Rectangle(pos=self.pos, size=self.size)
)
self.bind(pos=self.update_rect
)
self.bind(size=self.update_rect
_
def update rect(self, *args) :
self.rect.pos = self.pos
self.rect.size = self.size
classe MyWidget(Widget) :
__ __
def init (self, **kwargs):
_ __
super(MyWidget, self). _init (*kwargs)
_my
self.draw _stuff()
)
self.bind(pos=self.draw_my_stuff
)
self.bind(size=self.draw_my_stuff
_stuff *
def draw_my (self, args) :
self.canvas.clear()
avec self.canvas :
self.rect = Rectangle(pos=self.pos, size=self.size)
Veuillez noter que la mise à jour des instructions est considérée comme la meilleure pratique, car elle
implique moins de frais généraux et évite de créer de nouvelles instructions.
88
CHAPITRE
TREIZE
LANGUE KV
À mesure que votre application devient plus complexe, il est fréquent que la construction d’arbres de
widget et la déclaration explicite des liaisons deviennent verbeuses et difficiles à maintenir. La langue
KV est une tentative pour surmonter ces lacunes.
Le langage KV, parfois appelé kvlang ou le langage kivy, vous permet de créer votre arborescence de
manière déclarative et de lier les propriétés des widget les unes aux autres ou aux callbacks de
manière naturelle. It allows for very fast prototypes and agile changes to your UI. It also facilitates
separating the logic of your application and its User Interface.
If this file defines a Root Widget it will be attached to the App’s root attribute and used as the
base of the application widget tree.
• Builder: You can tell Kivy to directly load a string or a file. If this string or file defines a root
widget, it will be returned by the method:
_
Builder.load file('path/to/file.kv') or:
_ _
Builder.load string(kv string)
89
13.3 Rule context
A Kv source constitutes of rules which are used to describe the content of a Widget. You can have
one root rule, and any number of class or template rules.
The root rule is declared by declaring the class of your root widget, without any indentation, followed
by : and will be set as the root attribute of the App instance:
Widget:
A class rule, declared by the name of a widget class between < > and followed by :, defines the
appearance and behavior of any instance of that class:
<MyWidget>:
Rules use indentation for delimitation, like Python. Indentation should be four spaces per level, like
the Python style guide recommends.
There are three keywords specific to the Kv language:
• app: always refers to the instance of your application.
• root: refers to the base widget/template in the current rule
• self : always refer to the current widget
is equivalent to:
in Python.
To set a global value, use #:set
is equivalent to:
name = value
in Python.
90
13.5 Instantiate children
To declare a widget instance of some class as a child widget, just declare that child inside the rule:
MyRootWidget:
BoxLayout:
Button:
Button:
The example above defines that our root widget, an instance of MyRootWidget, has a child that is an
instance of the BoxLayout, and that BoxLayout further has two children, instances of the Button
class.
The Python equivalent of this code might be:
root = MyRootWidget()
box = BoxLayout()
_
box.add widget(Button())
_
box.add widget(Button())
_
root.add widget(box)
Which you may find less nice, both to read and to write.
Of course, in Python, you can pass keyword arguments to your widgets at creation to specify their
behaviour. For example, to set the number of columns of a gridlayout, we would do:
grid = GridLayout(cols=3)
To do the same thing in kv, you can set properties of the child widget directly in the rule:
GridLayout:
cols: 3
The value is evaluated as a Python expression, and all the properties used in the expression will be
observed, that means that if you had something like this in Python (this assume self is a widget with a
data ListProperty):
grid = GridLayout(cols=len(self.data))
self.bind(data=grid.setter('cols'))
To have your display updated when your data change, you can now have just:
GridLayout:
cols: len(root.data)
Note: Widget names should start with upper case letters while property names should start with lower
case ones. Following the PEP8 Naming Conventions is encouraged.
91
13.6 Event Bindings
You can bind to events in Kv using the “:” syntax, that is, associating a callback to an event:
Widget:
_ _
on size: my callback()
You can pass the values dispatched by the signal using the args keyword:
TextInput:
_
on text: app.search(args[1])
More complex expressions can be used, like:
_ _ _
pos: self.center x - self.texture size[0] / 2., self.center y - self.
size
,! texture_ [1] / 2.
_ _ _
This expression listens for a change in center x, center y, and texture size. If one of them
changes, the expression will be re-evaluated to update the pos field.
_
You can also handle on events inside your kv language. For example the TextInput class has a focus
_
property whose auto-generated on focus event can be accessed inside the kv language like so:
TextInput:
_
on focus: print(args)
Kv lang can be used to define the canvas instructions of your widget like this:
MyWidget:
canvas:
Color:
rgba: 1, .3, .8, .5
Line:
points: zip(self.data.x, self.data.y)
In a widget tree there is often a need to access/reference other widgets. The Kv Language provides a
way to do this using id’s. Think of them as class level variables that can only be used in the Kv
language. Consider the following:
<MyFirstWidget>:
Button:
_
id: f but
TextInput:
_
text: f but.state
(continues on next page)
92
(continued from previous page)
<MySecondWidget>:
Button:
_
id: s but
TextInput:
_
text: s but.state
_
An id is limited in scope to the rule it is declared in, so in the code above s but can not be accessed
outside the <MySecondWidget> rule.
Warning: When assigning a value to id, remember that the value isn’t a string. There are no quotes:
good -> id: value, bad -> id: 'valeur’
An id is a weakref to the widget and not the widget itself. As a consequence, storing the id is not
sufficient to keep the widget from being garbage collected. To demonstrate:
<MyWidget>:
_ _
label widget: label widget
Button:
text: 'Add Button'
_ _ _
on press: root.add widget(label widget)
Button:
text: 'Remove Button'
_ _ _
on press: root.remove widget(label widget)
Label:
_
id: label widget
text: 'widget'
_
Although a reference to label widget is stored in MyWidget, it is not sufficient to keep the object
alive once other references have been removed because it’s only a weakref. Therefore, after the
remove button is clicked (which removes any direct reference to the widget) and the window is
_
resized (which calls the garbage collector resulting in the deletion of label widget), when the add
button is clicked to add the widget back, a ReferenceError: weakly-referenced object no longer
exists will be thrown.
_
To keep the widget alive, a direct reference to the label widget widget must be kept. This is achieved
__ __ _ __ __
using id. self or label widget. self in this case. The correct way to do this would be:
<MyWidget>:
_ _ __ __
label widget: label widget. self
<MyFirstWidget>:
# both these variables can be the same name and this doesn't lead to
# an issue with uniqueness as the id is only accessible in kv.
_ _
txt inpt: txt inpt
Button:
_
id: f but
TextInput:
(continues on next page)
93
(continued from previous page)
_
id: txt inpt
_
text: f but.state
_ _ _
on text: root.check status(f but)
In myapp.py:
...
class MyFirstWidget(BoxLayout):
_
txt inpt = ObjectProperty(None)
_
def check status(self, btn):
print('button state is: {state}'.format(state=btn.state))
_
print('text input text is: {txt}'.format(txt=self.txt inpt))
...
_
txt inpt = ObjectProperty(None)
At this point self.txt_inpt is None. In Kv lang this property is updated to hold the instance of the
TextInput referenced by the id txt_inpt.:
_ _
txt inpt: txt inpt
From this point onwards, self.txt_inpt holds a reference to the widget identified by the id txt_input and
can be used anywhere in the class, as in the function check_status. In contrast to this method you
could also just pass the id to the function that needs to use it, like in case of f_but in the code above.
There is a simpler way to access objects with id tags in Kv using the ids lookup object. You can do
this as follows:
<Marvel>
Label:
id: loki
text: 'loki: I AM YOUR GOD!'
Button:
id: hulk
text: "press to smash loki"
_ _
on release: root.hulk smash()
In your Python code:
class Marvel(BoxLayout):
_
def hulk smash(self):
self.ids.hulk.text = "hulk: puny god!"
_
self.ids["loki"].text = "loki: > <!!!" # alternative syntax
When your kv file is parsed, kivy collects all the widgets tagged with id’s and places them in this
self.ids dictionary type property. That means you can also iterate over these widgets and access them
dictionary style:
94
Note: Although the self.ids method is very concise, it is generally regarded as ‘best practice’ to use
the ObjectProperty. This creates a direct reference, provides faster access and is more explicit.
<MyWidget>:
Button:
text: "Hello world, watch this text wrap inside the button"
_
text size: self.size
_
font size: '25sp'
markup: True
Button:
text: "Even absolute is relative to itself"
_
text size: self.size
_
font size: '25sp'
markup: True
Button:
text: "Repeating the same thing over and over in a comp = fail"
_
text size: self.size
_
font size: '25sp'
markup: True
Button:
Instead of having to repeat the same values for every button, we can just use a template instead, like so:
<MyBigButton@Button> :
_
text size: self.size
_
font size: '25sp'
markup: True
<MyWidget>:
MyBigButton:
text: "Hello world, watch this text wrap inside the button"
MyBigButton:
text: "Even absolute is relative to itself"
MyBigButton:
text: "repeating the same thing over and over in a comp = fail"
MyBigButton:
This class, created just by the declaration of this rule, inherits from the Button class and allows us to
change default values and create bindings for all its instances without adding any new code on the
Python side.
95
13.11 Re-using styles in multiple widgets
<MyFirstWidget>:
Button:
_ _
on press: root.text(txt inpt.text)
TextInput:
_
id: txt inpt
<MySecondWidget>:
Button:
_ _
on press: root.text(txt inpt.text)
TextInput:
_
id: txt inpt
In myapp.py:
class MyFirstWidget(BoxLayout):
class MySecondWidget(BoxLayout):
writing = StringProperty('')
Because both classes share the same .kv style, this design can be simplified if we reuse that style for
both widgets. You can do this in .kv as follows. In my.kv:
<MyFirstWidget,MySecondWidget>:
Button:
_ _
on press: root.text(txt inpt.text)
TextInput:
_
id: txt inpt
By separating the class names with a comma, all the classes listed in the declaration will have the
same kv properties.
96
13.12 Designing with the Kivy Language
One of the aims of the Kivy language is to separate the concerns of presentation and logic. The
presentation (layout) side is addressed by your kv file and the logic by your .py file.
import kivy
kivy.require('1.0.5')
class Controller(FloatLayout):
'''Create a controller that receives a custom widget from the kv lang ,! file.
class ControllerApp(App):
def build(self):
return Controller(info='Hello world')
__ __ __ __
if name == ' main ':
ControllerApp(). run()
97
13.12.2 The layout goes in controller.kv
Executing this application without a corresponding .kv file will work, but nothing will be shown on the
screen. This is expected, because the Controller class has no widgets in it, it’s just a FloatLayout.
We can create the UI around the Controller class in a file named controller.kv, which will be loaded
when we run the ControllerApp. How this is done and what files are loaded is described in the
_
kivy.app.App.load kv() method.
1
#:kivy 1.0
2
3
<Controller> :
4
_ _ _
5
label wid: my custom label
6
BoxLayout:
7
orientation: 'vertical'
8
padding: 20
9
10
Button:
11
text: 'My controller info is: ' + root.info
12 _ _
on press: root.do action()
13
14
Label:
15
_ _
id: my custom label
16
text: 'My label before button press'
One label and one button in a vertical BoxLayout. Seems very simple. There are 3 things going on
here:
1. Using data from the Controller. As soon as the info property is changed in the controller, the
expression text: 'My controller info is: ' + root.info will automatically be re-evaluated,
changing the text in the Button.
_ _
2. Giving data to the Controller. The expression id: my custom label is assigning the created
_ _ _ _
Label the id of my custom label. Then, using my custom label in the expression
_ _ _
label wid: my custom label gives the instance of that Label widget to your Controller.
_
3. Creating a custom callback in the Button using the Controller’s on press method.
• root and self are reserved keywords, usable anywhere. root represents the top
widget in the rule and self represents the current widget.
• You can use any id declared in the rule the same as root and self. For example,
_
you could do this in the on press():
Button:
_ _ _ _ _
on press: root.do action(); my custom label.font size = 18
And that’s that. Now when we run main.py, controller.kv will be loaded so that the Button and Label
will show up and respond to our touch events.
98
13.13 More documentation
For a full description of the different components of the KV language, advanced usage and
limitations, see the documentation for lang
99
100
CHAPTER
FOURTEEN
Note: You can use the kivy.support.install_twisted_reactor function to install a twisted reactor that will
run inside the kivy event loop.
Any arguments or keyword arguments passed to this function will be passed on the threadedse-lect
reactors interleave function. These are the arguments one would usually pass to twisted’s reac-
tor.startRunning
Warning: Unlike the default twisted reactor, the installed reactor will not handle any signals unless
you set the ‘installSignalHandlers’ keyword argument to 1 explicitly. This is done to allow kivy to
handle the signals as usual, unless you specifically want the twisted reactor to handle the signals
(e.g. SIGINT).
The kivy examples include a small example of a twisted server and client. The server app has a
simple twisted server running and logs any messages. The client app can send messages to the
server and will print its message and the response it got. The examples are based mostly on the
simple Echo example from the twisted docs, which you can find here:
• http://twistedmatrix.com/documents/current/_downloads/simpleserv.py
• http://twistedmatrix.com/documents/current/_downloads/simpleclient.py
To try the example, run echo_server_app.py first, and then launch echo_client_app.py. The server will
reply with simple echo messages to anything the client app sends when you hit enter after typing
something in the textbox.
101
14.1.1 Server App
_ _
# install twisted rector must be called before importing and using the ,! reactor
_ _
from kivy.support import install twisted reactor
_ _
install twisted reactor()
from twisted.internet import reactor
from twisted.internet import protocol
class EchoServer(protocol.Protocol):
def dataReceived(self, data):
_
response = self.factory.app.handle message(data)
if response:
self.transport.write(response)
class EchoServerFactory(protocol.Factory):
protocol = EchoServer
__ __
def init (self, app):
self.app = app
class TwistedServerApp(App):
label = None
def build(self):
self.label = Label(text="server started\n")
reactor.listenTCP(8000, EchoServerFactory(self)) return
self.label
_
def handle message(self, msg):
msg = msg.decode('utf-8')
self.label.text = "received: {}\n".format(msg)
if msg == "ping":
msg = "Pong"
if msg == "plop":
msg = "Kivy Rocks!!!"
self.label.text += "responded: {}\n".format(msg)
return msg.encode('utf-8')
__ __ __ __
if name == ' main ':
TwistedServerApp(). run()
102
14.1.2 Client App
_ _
# install twisted rector must be called before importing the reactor from
__ __ _
future import unicode literals
_ _
from kivy.support import install twisted reactor
_ _
install twisted reactor()
# A Simple Client that send messages to the Echo Server from
twisted.internet import reactor, protocol
class EchoClient(protocol.Protocol):
def connectionMade(self):
_
self.factory.app.on connection(self.transport)
def dataReceived(self, data):
_
self.factory.app.print message(data.decode('utf-8'))
class EchoClientFactory(protocol.ClientFactory):
protocol = EchoClient
__ __
def init (self, app):
self.app = app
def build(self):
_
root = self.setup gui()
_ _
self.connect to server()
(continues on next page)
103
(continued from previous page)
return root
_
def setup gui(self):
_ _
self.textbox = TextInput(size hint y=.1, multiline=False)
_ _ _
self.textbox.bind(on text validate=self.send message)
self.label = Label(text='connecting...\n')
layout = BoxLayout(orientation='vertical')
_
layout.add widget(self.label)
_
layout.add widget(self.textbox)
return layout
_ _
def connect to server(self):
reactor.connectTCP('localhost', 8000, EchoClientFactory(self))
_
def on connection(self, connection):
_
self.print message("Connected successfully!")
self.connection = connection
_
def send message(self, *args):
msg = self.textbox.text
if msg and self.connection:
self.connection.write(msg.encode('utf-8'))
self.textbox.text = ""
_
def print message(self, msg):
self.label.text += "{}\n".format(msg)
__ __ __ __
if name == ' main ':
TwistedClientApp(). run()
104
CHAPTER
FIFTEEN
Note: This document only applies for kivy 1.9.1 and greater.
Packaging your application for the Windows platform can only be done inside the Windows OS. The
following process has been tested on Windows with the Kivy wheels installation, see at the end for
alternate installations.
The package will be either 32 or 64 bits depending on which version of Python you ran it with.
15.1.1 Requirements
This section applies to PyInstaller (>= 3.1) that includes the kivy hooks. To overwrite the default hook
the following examples need to be slightly modified. See Overwriting the default hook.
For this example, we’ll package the touchtracer example project and embed a custom icon. The
location of the kivy examples is, when using the wheels, installed to python\\share\\kivy-examples
and when using the github source code installed as kivy\\examples. We’ll just refer to the full path
leading to the examples as examples-path. The touchtracer example is in examples-path\\demo\
\touchtracer and the main file is named main.py.
1. Open your command line shell and ensure that python is on the path (i.e. python works).
2. Create a folder into which the packaged app will be created. For example create a TouchApp
folder and change to that directory with e.g. cd TouchApp. Then type:
105
You can also add an icon.ico file to the application folder in order to create an icon for the
executable. If you don’t have a .ico file available, you can convert your icon.png file to ico using
the web app ConvertICO. Save the icon.ico in the touchtracer directory and type:
Then, find COLLECT() and add the data for touchtracer (touchtracer.kv, particle.png, . . . ):
Change the line to add a Tree() object, e.g. Tree('examples-path\\demo\\touchtracer\\'). This
Tree will search and add every file found in the touchtracer directory to your final package.
To add the dependencies, before the first keyword argument in COLLECT add a Tree object for
_ _
every path of the dependencies. E.g. *[Tree(p) for p in (sdl2.dep bins + glew. dep bins)] so
it’ll look something like:
coll = COLLECT(exe, Tree('examples-path\\demo\\touchtracer\\'), a.binaries,
a.zipfiles,
a.datas,
_ _
*[Tree(p) for p in (sdl2.dep bins + glew.dep bins)], strip=False,
upx=True,
name='touchtracer')
Next, we will modify the example above to package the touchtracer example project as a single file
application. Following the same steps as above, instead issue the following command:
1. As before, this will generate touchtracer.spec, which we will edit to add the dependencies. In
this instance, edit the arguments to the EXE command so that it will look something like this:
a.binaries,
a.zipfiles,
a.datas,
_ _
*[Tree(p) for p in (sdl2.dep bins + glew.dep bins)], upx=True
name='touchtracer')
106
2. Now you can build the spec file as before with:
3. The compiled package will be in the TouchApp\dist directory and will consist of a single
executable file.
We will again modify the previous example to include bundled data files. PyInstaller allows inclusion
of outside data files (such as images, databases, etc) that the project needs to run. When running an
app on Windows, the executable extracts to a temporary folder which the Kivy project doesn’t know
about, so it can’t locate these data files. We can fix that with a few lines.
1. First, follow PyInstaller documentation on how to include data files in your application.
2. Modify your main python code to include the following imports (if it doesn’t have them already):
Following we’ll slightly modify the example above to package a app that uses gstreamer for video.
We’ll use the videoplayer example found at examples-path\widgets\videoplayer.py. Create a
folder somewhere called VideoPlayer and on the command line change your current directory to that
folder and do:
to create the gstvideo.spec file. Edit as above and this time include the gstreamer dependency as
well:
_
from kivy deps import sdl2, glew, gstreamer
and add the Tree() to include the video files, e.g. Tree('examples-path\\widgets') as well as the
gstreamer dependencies so it should look something like:
a.zipfiles,
a.datas,
_ _ _
*[Tree(p) for p in (sdl2.dep bins + glew.dep bins + ,!gstreamer.dep bins)],
strip=False,
(continues on next page)
107
(continued from previous page)
upx=True,
name='gstvideo')
and you should find gstvideo.exe in VideoPlayer\dist\gstvideo, which when run will play a video.
Note: If you’re using Pygame and need PyGame in your packaging app, you’ll have to add the
following code to your spec file due to kivy issue #1638. After the imports add the following:
PyInstaller includes a hook for kivy that by default adds all the core modules used by kivy, e.g. audio,
video, spelling etc (you still need to package the gstreamer dlls manually with Tree() - see the
example above) and their dependencies. If the hook is not installed or to reduce app size some of
these modules may be excluded, e.g. if no audio/video is used, with an alternative hook.
Kivy provides the alternate hook at hookspath(). In addition, if and only if PyInstaller doesn’t have the
_
default hooks runtime hooks() must also be provided. When overwriting the hook, the latter one
typically is not required to be overwritten.
The alternate hookspath() hook does not include any of the kivy providers. To add them, they have to be
_ _ _ _ _
added with get deps minimal() or get deps all(). See their documentation and pyinstaller hooks for
_ _
more details. But essentially, get deps all() add all the providers like in the default hook while
_ _
get deps minimal() only adds those that are loaded when the app is run. Each method provides a list of
hidden kivy imports and excluded imports that can be passed on to Analysis.
One can also generate a alternate hook which literally lists every kivy provider module and those not
_
required can be commented out. See pyinstaller hooks.
To use the the alternate hooks with the examples above modify as following to add the hooks with
_ _ _ _ _
hookspath() and runtime hooks (if required) and **get deps minimal() or **get deps all()
to specify the providers.
For example, add the import statement:
_ _ _ _ _
from kivy.tools.packaging.pyinstaller hooks import get deps minimal, get ,!deps all,
_
hookspath, runtime hooks
108
and then modify Analysis as follows:
You can create a package for android using the python-for-android project. This page explains how to
download and use it directly on your own machine (see Packaging with python-for-android) or use the
Buildozer tool to automate the entire process. You can also see Packaging your application for the
Kivy Launcher to run kivy programs without compiling them.
For new users, we recommend using Buildozer as the easiest way to make a full APK. You can also
run your Kivy app without a compilation step with the Kivy Launcher app.
Kivy applications can be released on an Android market such as the Play store, with a few extra steps
to create a fully signed APK.
The Kivy project includes tools for accessing Android APIs to accomplish vibration, sensor access,
texting etc. These, along with information on debugging on the device, are documented at the main
Android page.
109
15.4.1 Buildozer
Buildozer is a tool that automates the entire build process. It downloads and sets up all the
prerequisites for python-for-android, including the android SDK and NDK, then builds an apk that can
be automatically pushed to the device.
Buildozer currently works only in Linux, and is a beta release, but it already works well and can
significantly simplify the apk build.
You can get buildozer at https://github.com/kivy/buildozer:
This will install buildozer in your system. Afterwards, navigate to your project directory and run:
buildozer init
This creates a buildozer.spec file controlling your build configuration. You should edit it appropriately
with your app name etc. You can set variables to control most or all of the parameters passed to
python-for-android.
Install buildozer’s dependencies.
Finally, plug in your android device and run:
You can also package directly with python-for-android, which can give you more control but requires
you to manually download parts of the Android toolchain.
See the python-for-android documentation for full details.
The Kivy launcher is an Android application that runs any Kivy examples stored on your SD Card. To
install the Kivy launcher, you must:
1. Go to the Kivy Launcher page on the Google Play Store
2. Click on Install
3. Select your phone. . . And you’re done!
If you don’t have access to the Google Play Store on your phone/tablet, you can download and install
the APK manually from http://kivy.org/#download.
Once the Kivy launcher is installed, you can put your Kivy applications in the Kivy directory in your
external storage directory (often available at /sdcard even in devices where this memory is internal),
e.g.
110
/sdcard/kivy/<yourapplication>
title=<Application Title>
author=<Your Name>
orientation=<portrait|landscape>
These options are just a very basic configuration. If you create your own APK using the tools above,
you can choose many other settings.
Installation of Examples
Kivy comes with many examples, and these can be a great place to start trying the Kivy launcher. You
can run them as below:
/sdcard/kivy
1. Run the launcher and select one of the Pictures, Showcase, Touchtracer, Cymunk or other de-
mos. . .
If you have built your own APK with Buildozer or with python-for-android, you can create a release
version that may be released on the Play store or other Android markets.
To do this, you must run Buildozer with the release parameter (e.g. buildozer android release), or if
using python-for-android use the --release option to build.py. This creates a release APK in the bin
directory, which you must properly sign and zipalign. The procedure for doing this is described in the
Android documentation at https://developer.android.com/studio/publish/ app-signing.html#signing-
manually - all the necessary tools come with the Android SDK.
111
15.4.5 Targeting Android
Kivy is designed to operate identically across platforms and as a result, makes some clear design
decisions. It includes its own set of widgets and by default, builds an APK with all the required core
dependencies and libraries.
It is possible to target specific Android features, both directly and in a (somewhat) cross-platform way.
See the Using Android APIs section of the Kivy on Android documentation for more details.
You can run Kivy applications on Android, on (more or less) any device with OpenGL ES 2.0 (Android
2.2 minimum). This is standard on modern devices; Google reports the requirement is met by 99.9%
of devices.
Kivy APKs are normal Android apps that you can distribute like any other, including on stores like the
Play store. They behave properly when paused or restarted, may utilise Android services and have
access to most of the normal java API as described below.
Follow the instructions below to learn how to package your app for Android, debug your code on the
device, and use Android APIs such as for vibration and reading sensors.
The Kivy project provides all the necessary tools to package your app on Android, including building
your own standalone APK that may be distributed on a market like the Play store. This is covered fully
in the Create a package for Android documentation.
You can view the normal output of your code (stdout, stderr), as well as the normal Kivy logs, through the
Android logcat stream. This is accessed through adb, provided by the Android SDK. You may need to
enable adb in your device’s developer options, then connect your device to your computer and run:
adb logcat
You’ll see all the logs including your stdout/stderr and Kivy logger.
If you packaged your app with Buildozer, the adb tool may not be in your $PATH and the above
command may not work. You can instead run:
to run the version installed by Buildozer, or find the SDK tools at $HOME/.buildozer/android/
platform.
You can also run and debug your application using the Kivy Launcher. If you run your application this
way, you will find log files inside the “/.kivy/logs” sub-folder within your application folder.
112
15.5.3 Using Android APIs
Although Kivy is a Python framework, the Kivy project maintains tools to easily use the normal java
APIs, for everything from vibration to sensors to sending messages through SMS or email.
For new users, we recommend using Plyer. For more advanced access or for APIs not currently
wrapped, you can use Pyjnius directly. Kivy also supplies an android module for basic Android func-
tionality.
User contributed Android code and examples are available on the Kivy wiki.
Plyer
Plyer is a pythonic, platform-independent API to use features commonly found on various platforms,
particularly mobile ones. The idea is that your app can call simply call a Plyer function, such as to
present a notification to the user, and Plyer will take care of doing so in the right way regardless of the
platform or operating system. Internally, Plyer uses Pyjnius (on Android), Pyobjus (on iOS) and some
platform specific APIs on desktop platforms.
For instance, the following code would make your Android device vibrate, or raise a NotImplemented-
Error that you can handle appropriately on other platforms such as desktops that don’t have
appropriate hardware::
Plyer’s list of supported APIs is growing quite quickly, you can see the full list in the Plyer README.
Pyjnius
Pyjnius is a Python module that lets you access java classes directly from Python, automatically
converting arguments to the right type, and letting you easily convert the java results to Python.
Pyjnius can be obtained from github, and has its own documentation.
Here is a simple example showing Pyjnius’ ability to access the normal Android vibration API, the
same result of the plyer code above:
# 'autoclass' takes a java class and gives it a Python wrapper from jnius
import autoclass
PythonActivity = autoclass('org.renpy.android.PythonActivity')
# This is almost identical to the java code for the vibrator vibrator =
_
activity.getSystemService(Context.VIBRATOR SERVICE)
vibrateur.vibrate(10000) # The value is in milliseconds - this is 10s
113
This code directly follows the java API functions to call the vibrator, with Pyjnius automatically
translating the api to Python code and our calls back to the equivalent java. It is much more verbose
and java-like than Plyer’s version, for no benefit in this case, though Plyer does not wrap every API
available to Pyjnius.
Pyjnius also has powerful abilities to implement java interfaces, which is important for wrapping some
APIs, but these are not documented here - you can see Pyjnius’ own documentation.
Android module
Python-for-android includes a python module (actually cython wrapping java) to access a limited set
of Android APIs. This has been largely superseded by the more flexible Pyjnius and Plyer as above,
but may still occasionally be useful. The available functions are given in the python-for-android
documentation.
This includes code for billing/IAP and creating/accessing Android services, which is not yet available
in the other tools above.
These sections previously described the existence of Kivy’s Android build tools, with their limitations
and some devices that were known to work.
The Android tools are now quite stable, and should work with practically any device; our minimum
requirements are OpenGL ES 2.0 and Android 2.2. These are very common now - Kivy has even
been run on an Android smartwatch!
A current technical limitation is that the Android build tools compile only ARM APKs, which will not run
on Android devices with x86 processors (these are currently rare). This should be added soon.
As Kivy works fine on most devices, the list of supported phones/tablets has been retired - all Android
devices are likely to work if they meet the conditions above.
Note: This guide describes multiple ways for packaging Kivy applications. Packaging with PyInstaller
is recommended for general use.
Note: Kivy.app is built on the current GitHub Action macOS version (10.15) and will typically not work
on older OS X versions. For older OS X versions, you need to build Kivy.app on the oldest machine
you wish to support. See below.
For OS X 10.15+ and later, we provide a Kivy DMG with all dependencies bundled in a virtual
environment, including a Python interpreter that can be used as a base to package kivy apps.
114
This is the safest approach because it packages the binaries without references to any binaries on the
system on which the app is packaged. Because all references are to frameworks included in the dmg
or to binaries with the dmg. As opposed to e.g. pyinstaller which copies binaries from your local
python installation.
You can find complete instructions to build and package apps with Kivy.app, starting either with
Kivy.app or building from scratch, in the readme of the kivy-sdk-packager repo.
Note: Package your app on the oldest OS X version you want to support.
Complete guide
1. Install Homebrew
2. Install Python:
Note: To use Python 3, brew install python3 and replace pip with pip3 in the guide below.
3. (Re)install your dependencies with --build-from-source to make sure they can be used on
other machines:
_ _ _
$ brew reinstall --build-from-source sdl2 sdl2 image sdl2 ttf sdl2 ,!mixer
Note: If your project depends on GStreamer or other additional libraries (re)install them with --
build-from-source as described below.
5. Install PyInstaller:
115
Note: This will not yet copy additional image or sound files. You would need to adapt the
created .spec file for that.
The specs file is named touchtracer.spec and is located in the directory where you ran the pyinstaller
command.
You need to change the COLLECT() call to add the data of touchtracer (touchtracer.kv, particle.png, . . . ).
Change the line to add a Tree() object. This Tree will search and add every file found in the touchtracer
directory to your final package. Your COLLECT section should look something like this:
a. binaires,
a.zipfiles,
a.datas,
strip=None,
upx=True,
name='touchtracer')
This will add the required hooks so that PyInstaller gets the required Kivy files. We are done. Your
spec is ready to be executed.
1. Open a console.
2. Go to the PyInstaller directory, and build the spec:
3. Run:
$ pushd dist
$ hdiutil create ./Touchtracer.dmg -srcfolder touchtracer.app -ov $ popd
Additional Libraries
GStreamer
Note: If your Project needs Ogg Vorbis support be sure to add the --with-libvorbis option to the
command above.
116
Traduit de Anglais vers Français - www.onlinedoctranslator.com
Partie IV
RÉFÉRENCE API
La référence API est une liste lexicographique de toutes les différentes classes, méthodes et fonctionnalités proposées par Kivy.
155
156
CHAPITRE
VINGT
CADRE KIVY
Kivy est une bibliothèque open source pour le développement d'applications multi-touch.
C'est multiplateforme
(Linux/OSX/Windows/Android/iOS) et publié sous les termes de laLicence MIT.
Il est livré avec une prise en charge native de nombreux périphériques d'entrée multi-touch, une bibliothèque croissante de widgets
multi-touch et un dessin OpenGL accéléré par le matériel. Kivy est conçu pour vous permettre de vous concentrer sur la création
d'applications personnalisées et hautement interactives aussi rapidement et facilement que possible.
Avec Kivy, vous pouvez profiter pleinement de la nature dynamique de Python. Il existe des milliers de bibliothèques gratuites de haute
qualité qui peuvent être intégrées dans votre application. Dans le même temps, les pièces critiques en termes de performances sont
mises en œuvre à l'aide deCython.
kivy.kivy_base_dir = '/home/docs/checkouts/readthedocs.org/user_builds/kivy/envs/latest/
lib/python3.7/site-packages/kivy'
Annuaire Kivy
kivy.kivy_config_fn = ''
Nom du fichier de configuration Kivy
kivy.kivy_configure()
Appelez la post-configuration de Kivy. Cette fonction doit être appelée si vous créez vous-même la fenêtre.
kivy.kivy_data_dir = '/home/docs/checkouts/readthedocs.org/user_builds/kivy/envs/latest/
lib/python3.7/site-packages/kivy/data'
Annuaire de données Kivy
kivy.kivy_examples_dir = '/home/docs/checkouts/readthedocs.org/user_builds/kivy/envs/latest/
share/kivy-examples'
Répertoire d'exemples Kivy
kivy.kivy_home_dir = ''
Répertoire de stockage utilisateur Kivy
kivy.kivy_icons_dir = '/home/docs/checkouts/readthedocs.org/user_builds/kivy/envs/latest/
lib/python3.7/site-packages/kivy/data/icons/'
Chemin de configuration des icônes Kivy (ne supprimez pas le dernier '')
157
kivy.kivy_register_post_configuration(rappeler)
Enregistrez une fonction à appeler lorsque kivy_configure() est appelé.
kivy.kivy_shader_dir = '/home/docs/checkouts/readthedocs.org/user_builds/kivy/envs/latest/
lib/python3.7/site-packages/kivy/data/glsl'
Répertoire des shaders Kivy glsl
kivy.kivy_usermodules_dir = ''
Répertoire des modules utilisateur Kivy
kivy.parse_kivy_version(version)
Analyse la version kivy comme décrit dans exiger() dans un 3-uplet de ([x, y, z], 'rc|a|b|dev|post', 'N') où N est la
révision de la balise. Les deux derniers éléments peuvent être Aucun.
kivy.exiger(version)
Require peut être utilisé pour vérifier la version minimale requise pour exécuter une application Kivy. Par exemple, vous
pouvez démarrer votre code d'application comme ceci :
importer kivy
kivy.exiger('1.0.1')
Si un utilisateur tente d'exécuter votre application avec une version de Kivy antérieure à la version spécifiée, une
exception est déclenchée.
X.Oui.Z[étiqueter[révision de balise]]
La balise est facultative, mais peut être l'une des suivantes : '.dev', '.post', 'a', 'b' ou 'rc'. Le tagrevision est le numéro de
révision du tag.
Avertissement: Vous ne devez pas demander une version avec une balise, sauf -dev. Demander une version 'dev'
avertira simplement l'utilisateur si la version actuelle de Kivy n'est pas une -dev, mais cela ne lèvera jamais
d'exception. Vous ne devez pas demander une version avec une baliserévision.
20.2 Animation
Animation et AnimationTransition sont utilisés pour animer Widget Propriétés. Vous devez spécifier au moins un nom
de propriété et une valeur cible. Pour utiliser une animation, procédez comme suit :
158
20.2.1 Animations simples
Pour animer la position x ou y d'un widget, spécifiez simplement les valeurs x/y cibles où vous souhaitez que le widget
soit positionné à la fin de l'animation :
L'animation durera 1 seconde à moins que durée est spécifié. Lorsque anim.start() est appelé, le Widget se
déplacera en douceur de la position x/y actuelle à (100, 100).
Vous pouvez animer plusieurs propriétés et utiliser des fonctions de transition intégrées ou personnalisées à l'aide de transition
(ou la t= raccourci). Par exemple, pour animer la position et la taille à l'aide de la transition 'in_quad' :
Notez que le t= le paramètre peut être le nom de chaîne d'une méthode dans le AnimationTransition classe ou votre
propre fonction d'animation.
Pour joindre les animations de manière séquentielle, utilisez l'opérateur '+'. L'exemple suivant s'animera à x=50 sur 1 seconde,
puis animera la taille à (80, 80) au cours des deux prochaines secondes :
Pour joindre des animations en parallèle, utilisez l'opérateur '&'. L'exemple suivant animera la position à
(80, 10) sur 1 seconde, tout en animant en parallèle la taille à (800, 800) :
Gardez à l'esprit que la création d'animations qui se chevauchent sur la même propriété peut avoir des résultats
inattendus. Si vous souhaitez appliquer plusieurs animations à la même propriété, vous devez soit les planifier de
manière séquentielle (via l'opérateur '+' ou en utilisant leon_complete rappel) ou annuler les animations précédentes en
utilisant le Tout annuler méthode.
159
20.2.5 Répétition d'animation
Noter: Ceci n'est actuellement implémenté que pour les animations 'Sequence'.
Pour définir une animation à répéter, définissez simplement le Séquence.répéter propriété à Vrai:
Pour le contrôle de flux d'animations telles que l'arrêt et l'annulation, utilisez les méthodes déjà en place dans le module
d'animation.
classer kivy.animation.Animation(**kw)
Bases : kivy.event.EventDispatcher
Créez une définition d'animation qui peut être utilisée pour animer un widget.
Paramètres
durée ou ré: flottant, la valeur par défaut est 1. Durée de l'animation, en secondes.
transition ou t: str ou func Fonction de transition pour les propriétés animées. Cela peut être le
nom d'une méthode de AnimationTransition.
étape ou s: flotter Étape en millisecondes de l'animation. La valeur par défaut est 0, ce qui signifie
l'animation est mise à jour pour chaque image.
Pour mettre à jour l'animation moins souvent, définissez la valeur du pas sur un flottant. Par exemple, si
vous souhaitez animer à 30 FPS, utilisez s=1/30.
Événements
on_start: animation, widget Lancé lorsque l'animation est lancée sur un widget.
Modifié dans la version 1.10.0 : la valeur par défaut du paramètre step a été modifiée de 1/60. à 0.
propriété animée_propriétés
Renvoie les propriétés utilisées pour l'animation.
Annuler(widget)
Annuler l'animation précédemment appliquée à un widget. Même effet quearrêter, à l'exception du on_complete
l'événement sera ne pas être déclenché !
Exemple:
anime = Animation(X=50)
anime.début(widget)
(suite à la page suivante)
160
(suite de la page précédente)
# et ensuite
Animation.Tout annuler(widget, 'X')
Modifié dans la version 2.1.0 : Si le paramètre widget est Aucun, tous les widgets animés seront la
cible et annulés. Sigrands est également donné, l'animation de ces propriétés sera annulée pour tous
les widgets animés.
annuler_propriété(widget, soutenir)
Même si une animation est en cours d'exécution, supprimez une propriété. Il ne sera pas animé davantage.
Si c'était la seule/dernière propriété animée, l'animation sera annulée (voirAnnuler)
durée de la propriété
Renvoie la durée de l'animation.
have_properties_to_animer(widget)
Renvoie True si un widget a encore des propriétés à animer.
début(widget)
Démarrez l'animation sur un widget.
arrêter(widget)
Arrêter l'animation précédemment appliquée à un widget, déclenchant le on_complete un événement.
Exemple:
anime = Animation(X=50)
anime.début(widget)
# et ensuite
Animation.arrête tout(widget, 'X')
stop_propriété(widget, soutenir)
Même si une animation est en cours d'exécution, supprimez une propriété. Il ne sera pas animé davantage.
Si c'était la seule/dernière propriété animée, l'animation sera arrêtée (voirarrêter).
transition de propriété
Renvoie la transition de l'animation.
classer kivy.animation.AnimationTransition
Bases : Builtins.object
Collection de fonctions d'animation à utiliser avec l'objet Animation. Fonctions d'assouplissement portées
sur Kivy à partir du projet Clutterhttps://developer.gnome.org/clutter/stable/ClutterAlpha.html
le le progrès paramètre dans chaque fonction d'animation est dans la plage 0-1.
161
statique à l'arrière(le progrès)
162
statique in_out_back(le progrès)
163
statique in_out_quad(le progrès)
164
statique in_quint(le progrès)
165
statique out_cubique(le progrès)
166
statique out_sine(le progrès)
20.3 Candidature
le Application class est la base pour créer des applications Kivy. Considérez-le comme votre principal point d'entrée dans la boucle de
course Kivy. Dans la plupart des cas, vous sous-classez cette classe et créez votre propre application. Vous créez une instance de votre
classe d'application spécifique, puis, lorsque vous êtes prêt à démarrer le cycle de vie de l'application, vous appelez votre instance
App.run() méthode.
Pour initialiser votre application avec une arborescence de widgets, remplacez le construire() dans votre classe d'application et renvoyez
l'arborescence de widgets que vous avez construite.
'''
Exemple d'application utilisant build() + return
==========================================
Une application peut être construite si vous retournez un widget sur build(), ou si vous
→ ensemble
??
auto.racine.
'''
importer kivy
kivy.exiger('1.0.7')
déf construire(soi):
# renvoie un Button() en tant que widget racine
retourner Bouton(texte='Bonjour le monde')
si __Nom__ == '__principale__':
Application de test().Cours()
Le fichier est également disponible dans le dossier des exemples à l'adresse kivy/examples/application/
app_with_build.py.
167
Ici, aucun arbre de widget n'a été construit (ou si vous voulez, un arbre avec uniquement le nœud racine).
Vous pouvez également utiliser le Langue Kivy pour la création d'applications. Le .kv peut contenir des règles et des définitions
de widget racine en même temps. Voici le même exemple que celui de Button dans un fichier kv.
Contenu de 'test.kv' :
# :kivy 1.0
Bouton:
texte: 'Bonjour de test.kv'
Contenu de 'main.py' :
'''
Application construite à partir d'un fichier .kv
===================================
Cela montre comment utiliser implicitement un fichier .kv pour votre application. Vous
devriez voir un bouton en plein écran intitulé "Bonjour de test.kv".
Une fois que Kivy a instancié une sous-classe d'App, il recherche implicitement un fichier .kv.
Le fichier test.kv est sélectionné car le nom de la sous-classe de App
→
?? est
TestApp, ce qui implique que kivy devrait essayer de charger "test.kv". Ce fichier contient
un widget racine.
'''
importer kivy
kivy.exiger('1.0.7')
passe
si __Nom__ == '__principale__':
Application de test().Cours()
Voir kivy/examples/application/app_with_kv.py.
La relation entre main.py et test.kv est expliquée dans App.load_kv().
168
20.3.2 Paramétrage des applications
Votre application peut avoir besoin de son propre fichier de configuration. leApplication La classe gère automatiquement les
fichiers 'ini' si vous ajoutez la paire clé-valeur de la section au App.build_config() méthode utilisant le configuration paramètre
(une instance de ConfigParser):
Dès que vous ajoutez une section à la config, un fichier est créé sur le disque (voir get_application_config
pour son emplacement) et nommé en fonction du nom de votre classe. « TestApp » donnera un fichier de
configuration nommé « test.ini » avec le contenu :
[section 1]
clé1 = valeur1
clé2 = 42
Le « test.ini » sera automatiquement chargé au moment de l'exécution et vous pourrez accéder à la configuration dans votre
App.build() méthode:
déf construire(soi):
configuration = soi.configuration
retourner Étiqueter(texte='key1 est %s et key2 est %d' % (
configuration.avoir('section 1', 'clé1'),
configuration.obtenir('section 1', 'clé2')))
169
Créer un panneau de paramètres
Votre application peut avoir un panneau de paramètres pour permettre à votre utilisateur de configurer certains de vos jetons de
configuration. Voici un exemple réalisé dans l'exemple KinectViewer (disponible dans le répertoire des exemples) :
Vous pouvez ajouter vos propres panneaux de paramètres en étendant le App.build_settings() méthode. Vérifier laRéglages
sur la façon de créer un panneau, car vous avez d'abord besoin d'un fichier / de données JSON.
Prenons comme exemple l'extrait précédent de TestApp avec une configuration personnalisée. Nous pourrions créer un JSON comme
ceci :
[
{ "taper": "Titre",
"Titre": "Tester l'application" },
Ensuite, nous pouvons créer un panneau en utilisant ce JSON pour créer automatiquement toutes les options et les lier à notre
App.config Instance ConfigParser :
#...
déf build_settings(soi, réglages):
jsondata = """... mettez les données json ici...""" réglages.
add_json_panel(« Test d'application »,
soi.configuration, Les données=jsondata)
C'est tout! Vous pouvez maintenant appuyer sur F1 (touche par défaut) pour basculer le panneau des paramètres ou appuyer sur la
touche « paramètres » de votre appareil Android. Vous pouvez appeler manuellementApp.open_settings() et App. close_settings()si
vous souhaitez gérer cela manuellement. Chaque changement dans le panneau est automatiquement enregistré dans le fichier de
configuration.
170
Vous pouvez aussi utiliser App.build_settings() pour modifier les propriétés du panneau des paramètres. Par exemple, le
panneau par défaut a une barre latérale pour basculer entre les panneaux json dont la largeur par défaut est 200dp. Si vous
préférez que cela soit plus étroit, vous pouvez ajouter :
réglages.interface.menu.largeur = dp(100)
#...
déf on_config_change(soi, configuration, section, clé, valeur):
si configuration est soi.configuration:
jeton = (section, clé)
si jeton == ('section 1', 'clé1'):
imprimer('Notre clé1 a été changée en', valeur) elif jeton ==
('section 1', 'clé2'):
imprimer('Notre clé2 a été changée en', valeur)
Le panneau de configuration Kivy est ajouté par défaut à l'instance de paramètres. Si vous ne souhaitez pas ce panel, vous
pouvez déclarer votre Application comme suit :
use_kivy_settings = Faux
#...
Cela supprime uniquement le panneau Kivy mais n'empêche pas l'instance de paramètres d'apparaître. Si vous souhaitez empêcher
complètement l'instance de paramètres d'apparaître, vous pouvez procéder comme suit :
Il est souvent utile de profiler du code python afin de découvrir des emplacements à optimiser. Les profileurs de
bibliothèque standard (http://docs.python.org/2/library/profile.html) fournit plusieurs options pour le code de profilage.
Pour profiler l'ensemble du programme, les approches naturelles consistant à utiliser profile comme méthode
d'exécution de module ou de profile ne fonctionnent pas avec Kivy. Il est cependant possible d'utiliserApp.on_start() et
App.on_stop() méthodes :
importer cProfil
classer MonApp(Application):
déf on_start(soi): soi.profil = soi.
profil.activer() cProfil.Profil()
Cela créera un fichier appelé monapplication.profil lorsque vous quittez votre application.
171
20.3.4 Personnalisation de la mise en page
Vous pouvez choisir différentes dispositions de widget de paramètres en définissant App.settings_cls. Par défaut, il
s'agit d'un Réglages classe qui fournit la disposition de la barre latérale illustrée, mais vous pouvez la définir sur l'une
des autres dispositions fournies dans kivy.uix.settings ou créez le vôtre. Voir la documentation du module pour
kivy.uix.settings pour plus d'informations.
Vous pouvez personnaliser l'affichage du panneau des paramètres en remplaçant App.display_settings() qui est appelé avant
d'afficher le panneau des paramètres à l'écran. Par défaut, il dessine simplement le panneau en haut de la fenêtre, mais vous
pouvez le modifier pour (par exemple) afficher les paramètres dans unApparaitre ou ajoutez-le à votre application
Gestionnaire d'écran si vous en utilisez un. Si vous le faites, vous devez également modifierApp. close_settings()pour quitter le
panneau de manière appropriée. Par exemple, pour que le panneau des paramètres apparaisse dans une fenêtre contextuelle,
vous pouvez faire :
Enfin, si vous souhaitez remplacer le widget du panneau de paramètres actuel, vous pouvez supprimer les références
internes à celui-ci en utilisant App.destroy_settings(). Si vous avez modifiéApp.display_settings(), vous devez faire
attention à détecter si le panneau des paramètres a été remplacé.
Sur tablettes et téléphones, l'utilisateur peut basculer à tout moment vers une autre application. Par défaut, votre
application se fermera et leApp.on_stop() l'événement sera déclenché.
Si vous prenez en charge le mode Pause, lors du passage à une autre application, votre application attendra
indéfiniment jusqu'à ce que l'utilisateur revienne à votre application. Il y a un problème avec OpenGL sur les appareils
Android : il n'est pas garanti que le contexte OpenGL ES sera restauré lorsque votre application reprendra. Le
mécanisme de restauration de toutes les données OpenGL n'est pas encore implémenté dans Kivy.
1. Kivy vérifie à chaque image si le mode Pause est activé par le système d'exploitation en raison du passage de l'utilisateur à
une autre application, d'un arrêt du téléphone ou pour toute autre raison.
4. Si True est renvoyé (cas par défaut), l'application se mettra en veille jusqu'à ce que le système d'exploitation reprenne notre application.
172
5. Lorsque l'application est reprise, App.on_resume() est appelé.
6. Si la mémoire de notre application a été récupérée par le système d'exploitation, rien ne sera appelé.
déf on_pause(soi):
# Ici, vous pouvez enregistrer des données si
nécessaire retourner vrai
Avertissement: Les deux on_pause et on_stop doit sauvegarder les données importantes car après on_pause est appelé, pour
résumer peut ne pas être appelé du tout.
En plus d'exécuter une application normalement, Kivy peut être exécuté dans une boucle d'événements asynchrone telle que
fournie par le package asyncio de bibliothèque standard ou le package trio (fortement recommandé).
Fond
Normalement, lorsqu'une application Kivy est exécutée, elle bloque le thread qui l'exécute jusqu'à la fermeture de l'application. En interne, à chaque
itération d'horloge, il exécute tous les rappels d'applications, gère les graphiques et les entrées, et se met en veille en dormant pour le temps
restant.
Pour pouvoir s'exécuter de manière asynchrone, l'application Kivy peut ne pas dormir, mais doit à la place libérer le contrôle du
contexte d'exécution à la boucle d'événements asynchrone exécutant l'application Kivy. Nous le faisons lors de l'inactivité en
appelant les fonctions appropriées du package asynchrone utilisé au lieu de dormir.
Configuration asynchrone
Pour exécuter une application Kivy de manière asynchrone, soit le async_runTouchApp() ou App.async_run() coroutine doit
être planifié pour s'exécuter dans la boucle d'événements de la bibliothèque asynchrone utilisée.
init_async_lib() peut également être appelé directement pour définir l'utilisation de la bibliothèque asynchrone, mais il ne peut être
appelé qu'avant que l'application ne commence à s'exécuter avec async_runTouchApp() ou App.async_run().
Pour exécuter l'application de manière asynchrone, on planifie async_runTouchApp() ou App.async_run() pour s'exécuter dans la boucle
d'événements asynchrone de la bibliothèque donnée, comme dans les exemples ci-dessous. Kivy est alors traité comme une autre
coroutine que la bibliothèque donnée exécute dans sa boucle d'événements. En interne, Kivy utilisera l'API de la bibliothèque asynchrone
spécifiée, doncKIVY_EVENTLOOP ou async_lib doit correspondre à la bibliothèque asynchrone qui exécute Kivy.
Pour des exemples de base plus complets et plus avancés, consultez les applications de démonstration dans exemples/async.
173
Exemple d'Asyncio ~~~~~~~~~~~~~–
importer asynchrone
boucler = asynchrone.get_event_loop()
boucler.run_until_complete(
async_runTouchApp(Étiqueter(texte='Bonjour, Monde!'), async_lib='asynchrone'))
boucler.Fermer()
importer trio
Il est totalement sûr d'interagir avec n'importe quel objet kivy d'autres coroutines s'exécutant dans la même boucle
d'événement asynchrone. En effet, ils s'exécutent tous à partir du même thread et les autres coroutines ne sont
exécutées que lorsque Kivy est inactif.
De même, les rappels kivy peuvent interagir en toute sécurité avec des objets d'autres coroutines s'exécutant dans la même boucle
d'événement. Les règles normales à un seul thread s'appliquent dans les deux cas.
classer kivy.app.Application(**kwargs)
Bases : kivy.event.EventDispatcher
Classe d'application, voir la documentation du module pour plus d'informations.
Événements
pour résumer: Lancé lorsque l'application est reprise après une pause par le système d'exploitation. Faire attention:
vous n'avez aucune garantie que cet événement sera déclenché après le on_pause l'événement a
été appelé.
Modifié dans la version 1.8.0 : Paramètres fichier_kv et répertoire_kv sont maintenant des propriétés d'App.
174
async async_run(async_lib=Aucun)
Identique à Cours(), mais est une coroutine et peut être planifiée dans une boucle d'événement asynchrone en cours d'exécution.
construire()
Initialise l'application ; il ne sera appelé qu'une seule fois. Si cette méthode renvoie un widget (arbre),
il sera utilisé comme widget racine et ajouté à la fenêtre.
build_config(configuration)
Nouveau dans la version 1.0.7.
Cette méthode est appelée avant l'initialisation de l'application pour construire votre ConfigParser objet.
C'est ici que vous pouvez mettre n'importe quelle section / clé / valeur par défaut pour votre configuration.
Si quelque chose est défini, la configuration sera automatiquement enregistrée dans le fichier renvoyé par
get_application_config().
Paramètres
configuration: ConfigParser Utilisez ceci pour ajouter des éléments de section/clé/valeur par défaut
build_settings(réglages)
Nouveau dans la version 1.0.7.
Cette méthode est appelée lorsque l'utilisateur (ou vous) souhaitez afficher les paramètres de l'application. Il est appelé
une fois lors de la première ouverture du panneau des paramètres, après quoi le panneau est mis en cache. Il peut être
rappelé si le panneau des paramètres mis en cache est supprimé pardestroy_settings().
Vous pouvez utiliser cette méthode pour ajouter des panneaux de paramètres et pour personnaliser le widget de paramètres, par exemple en
modifiant la largeur de la barre latérale. Consultez la documentation du module pour plus de détails.
Paramètres
close_settings(*grand)
Fermez le panneau des paramètres précédemment ouvert.
configuration
Renvoie une instance du ConfigParser pour la configuration de l'application. Vous pouvez l'utiliser pour interroger
certains jetons de configuration dans leconstruire() méthode.
créer_paramètres()
Créez le panneau des paramètres. Cette méthode ne sera normalement appelée qu'une seule fois par durée de vie de
l'application et le résultat est mis en cache en interne, mais elle peut être appelée à nouveau si le panneau mis en cache est
supprimé pardestroy_settings().
détruire_paramètres()
Nouveau dans la version 1.8.0.
Déréférence le panneau de paramètres actuel s'il existe. Cela signifie que lorsque App.
open_settings() est la prochaine exécution, un nouveau panneau sera créé et affiché. Cela n'affecte pas
175
tout le contenu du panneau, mais vous permet (par exemple) d'actualiser la disposition du panneau de paramètres si vous
avez modifié le widget de paramètres en réponse à un changement de taille d'écran.
répertoire de propriétés
Nouveau dans la version 1.0.7.
Affichez le panneau des paramètres. Par défaut, le panneau est dessiné directement au-dessus de la fenêtre. Vous pouvez
définir un autre comportement en remplaçant cette méthode, par exemple en l'ajoutant à un ScreenManager ou à un
Popup.
réglages: Réglages Vous pouvez modifier cet objet afin de modifier les paramètres
affichage.
get_application_config(defaultpath='%(appdir)s/%(appname)s.ini')
Renvoyez le nom de fichier de la configuration de votre application. Selon la plateforme, le dossier de
candidature sera stocké à différents emplacements :
déf get_application_config(soi):
retourner super(Application de test, soi).get_application_config(
'~/.%(appname)s.ini')
Quelques notes:
Modifié dans la version 1.4.0 : Personnalisation du chemin par défaut pour les plates-formes iOS et Android. Ajout d'un
paramètre defaultpath pour les systèmes d'exploitation de bureau (ne s'applique pas à iOS et Android.)
Modifié dans la version 1.11.0 : Modification de la version Android pour utiliser le user_data_dir et a
ajouté un point manquant au nom du fichier de configuration iOS.
get_application_icon()
Renvoie l'icône de l'application.
get_application_name()
Renvoie le nom de l'application.
176
get_running_app statique()
Renvoie l'instance d'application en cours d'exécution.
icône
Icône de votre application. L'icône peut être située dans le même répertoire que votre fichier principal. Vous
pouvez le définir comme suit :
classer MonApp(Application):
déf construire(soi):
soi.icône = 'myicon.png'
Modifié dans la version 1.8.0 : icône est maintenant un Propriété de chaîne. Ne définissez pas l'icône dans la classe comme
indiqué précédemment dans la documentation.
Noter: Pour Kivy avant la version 1.8.0, vous devez définir ceci comme suit :
classer MonApp(Application):
icône = 'customicon.png'
Recommandé 256x256 ou 1024x1024 ? pour GNU/Linux et Mac OSX 32x32 pour Windows7 ou moins.
<= 256x256 pour Windows 8 256x256 fonctionne (au moins sur Windows 8), mais est réduit et n'a pas
l'air aussi beau qu'une icône 32x32.
répertoire_kv
Chemin du répertoire où l'application kv est stockée, par défaut Aucun
Si un kv_directory est défini, il sera utilisé pour obtenir le fichier kv initial. Par défaut, le fichier est supposé se trouver dans
le même répertoire que le fichier de définition d'application actuel.
fichier_kv
Nom de fichier du fichier Kv à charger, par défaut Aucun.
Si un fichier kv_file est défini, il sera chargé au démarrage de l'application. Le chargement du fichier kv « par
défaut » sera empêché.
load_config()
(interne) Cette fonction permet de renvoyer un ConfigParser avec la configuration de
l'application. Il fait 3 choses :
charge_kv(nom de fichier=Aucun)
Cette méthode est invoquée la première fois que l'application est exécutée si aucune arborescence de widgets n'a été
construite auparavant pour cette application. Cette méthode recherche ensuite un fichier kv correspondant dans le même
répertoire que le fichier contenant la classe d'application.
Par exemple, supposons que vous ayez un fichier nommé main.py qui contient :
177
classer ShowcaseApp(Application):
passe
Cette méthode recherchera un fichier nommé vitrine.kv dans le répertoire qui contient main.py.
Le nom du fichier kv doit être le nom en minuscule de la classe, sans le suffixe 'App' à la fin s'il
existe.
Vous pouvez définir des règles et un widget racine dans votre fichier kv :
Il ne doit y avoir qu'un seul widget racine. Voir leLangue Kivy documentation pour plus d'informations
sur la création de fichiers kv. Si votre fichier kv contient un widget racine, il sera utilisé comme
self.root, le widget racine de l'application.
Noter: Cette fonction est appelée à partir de Cours(), par conséquent, tout widget dont le style est défini
dans ce fichier kv et est créé avant Cours() est appelé (par exemple dans __init__), n'aura pas son style
appliqué. Noter queconstruire() est appelé après charge_kv a été appelé.
nom de la propriété
Nouveau dans la version 1.0.7.
on_pause()
Gestionnaire d'événements appelé lorsque le mode Pause est demandé. Vous devez retourner True si votre
application peut passer en mode Pause, sinon retourner False et votre application sera arrêtée.
Vous ne pouvez pas contrôler quand l'application va passer dans ce mode. Il est déterminé par le système
d'exploitation et principalement utilisé pour les appareils mobiles (android/ios) et pour le redimensionnement.
Modifié dans la version 1.10.0 : la valeur de retour par défaut est désormais True.
pour résumer()
Gestionnaire d'événements appelé lorsque votre application sort du mode Pause.
Avertissement: Lors de la reprise, le contexte OpenGL peut avoir été endommagé/libéré. C'est là que vous
pouvez reconstruire une partie de votre état OpenGL, par exemple le contenu FBO.
on_start()
Gestionnaire d'événements pour le on_start événement qui est déclenché après l'initialisation (après que build() a été
appelé) mais avant que l'application n'ait commencé à s'exécuter.
178
on_stop()
Gestionnaire d'événements pour le on_stop événement qui est déclenché lorsque l'application a fini de s'exécuter (c'est-à-
dire que la fenêtre est sur le point d'être fermée).
open_settings(*grand)
Ouvrez le panneau des paramètres de l'application. Il sera créé la toute première fois, ou recréé si le
panneau précédemment mis en cache a été supprimé pardestroy_settings(). Le panneau des
paramètres s'affichera avec leparamètres d'affichage() méthode, qui ajoute par défaut le panneau
des paramètres à la fenêtre attachée à votre application. Vous devez remplacer cette méthode si vous
souhaitez afficher le panneau des paramètres différemment.
options
Options passées au __init__ de l'App
racine
le racine widget renvoyé par le construire() méthode ou par le load_kv() méthode si le fichier kv
contient un widget racine.
propriété root_window
Nouveau dans la version 1.9.0.
Cours()
Lance l'application en mode autonome.
settings_cls
Nouveau dans la version 1.8.0.
La classe utilisée pour construire le panneau des paramètres et l'instance passée à build_config(). Vous
devez utiliser soitRéglages ou l'une des sous-classes fournies avec des mises en page différentes (
ParamètresAvec Barre Latérale, ParamètresAvecSpinner, ParamètresAvecTabbedPanel,
ParamètresAvecNoMenu). Vous pouvez également créer votre propre sous-classe Settings. Voir la
documentation deRéglages pour plus d'informations.
settings_cls est un Propriété de l'objet et par défaut à ParamètresAvecSpinner qui affiche des
panneaux de paramètres avec une flèche pour basculer entre eux. Si vous définissez une chaîne, le
Usine sera utilisé pour résoudre la classe.
arrêter(*grand)
Arrêtez l'application.
Titre
Titre de votre candidature. Vous pouvez le définir comme suit :
classer MonApp(Application):
déf construire(soi):
soi.Titre = 'Bonjour le monde'
Modifié dans la version 1.8.0 : Titre est maintenant un Propriété de chaîne. Ne définissez pas le titre dans la classe comme
indiqué précédemment dans la documentation.
Noter: Pour Kivy < 1.8.0, vous pouvez définir ceci comme suit :
classer MonApp(Application):
Titre = 'Titre personnalisé'
179
Si vous souhaitez modifier dynamiquement le titre, vous pouvez faire :
use_kivy_settings = Vrai
Nouveau dans la version 1.0.7.
Si True, les paramètres de l'application incluront également les paramètres Kivy. Si vous ne souhaitez pas que l'utilisateur modifie les
paramètres de Kivy à partir de votre interface utilisateur de paramètres, définissez-le sur False.
propriété user_data_dir
Nouveau dans la version 1.7.0.
Renvoie le chemin d'accès au répertoire dans le système de fichiers des utilisateurs que l'application peut utiliser pour stocker des
données supplémentaires.
Différentes plates-formes ont des conventions différentes en ce qui concerne l'endroit où l'utilisateur peut stocker
des données telles que les préférences, les jeux enregistrés et les paramètres. Cette fonction implémente ces
conventions. Le répertoire <app_name> est créé lorsque la propriété est appelée, sauf s'il existe déjà.
Sur iOS, ~/Documents/<nom_application> est renvoyé (qui se trouve dans le bac à sable de l'application).
Modifié dans la version 1.11.0 : Sur Android, cette fonction revenait auparavant /sdcard/<app_name>.
Ce dossier est devenu en lecture seule par défaut dans Android API 26 et le user_data_dir a donc été
déplacé vers un emplacement accessible en écriture.
async_lib est la bibliothèque async à utiliser. Voirkivy.app pour plus de détails et des exemples d'utilisation.
kivy.app.exécuterTouchApp(widget=Aucun, embarqué=Faux)
Fonction principale statique qui démarre la boucle d'application. Vous pouvez accéder à de la magie via les arguments
suivants :
Paramètres
<vide> Pour que la répartition fonctionne, vous avez besoin d'au moins un écouteur d'entrée. Si non,
l'application partira. (MTWindow agit comme un écouteur d'entrée)
widget Si vous ne passez qu'un widget, une MTWindow sera créée et votre widget
sera ajouté à la fenêtre en tant que widget racine.
widget + intégré Aucun envoi d'événement n'est effectué. Ce sera votre travail mais nous essayons
pour obtenir la fenêtre (doit être créée par vous au préalable) et y ajouter le widget.
Très utile pour intégrer Kivy dans une autre boîte à outils. (comme Qt, vérifiez
kivydesigned)
180
kivy.app.stopTouchApp()
Arrêtez l'application en cours en quittant la boucle principale.
C'est le chargeur asynchrone. Vous pouvez l'utiliser pour charger une image et l'utiliser, même si les données ne sont pas encore
disponibles. Vous devez spécifier une image de chargement par défaut lors de l'utilisation du chargeur :
image = Chargeur.image('http://monsite.com/test.png')
Si vous souhaitez modifier l'image de chargement par défaut, vous pouvez faire :
Vous pouvez modifier le chargeur pour offrir une meilleure expérience utilisateur ou plus de performances, en fonction
des images que vous allez charger. Regarde les paramètres :
• Loader.max_upload_per_frame - définir le nombre maximal de téléchargements d'images dans le GPU à effectuer par
image.
classer kivy.loader.ChargeurBase
Bases : Builtins.object
Base commune pour le Loader et implémentations spécifiques. Par défaut, le Loader sera la meilleure
implémentation de loader disponible.
La fonction _update() est appelée toutes les 1/25.s ou à chaque frame si nous avons moins de 25 FPS.
propriété error_image
Image utilisée pour l'erreur. Vous pouvez le changer en faisant :
class TestApp(App):
def _image_loaded(self, proxyImage):
(continues on next page)
181
(continued from previous page)
if proxyImage.image.texture:
self.image.texture = proxyImage.image.texture
def build(self):
proxyImage = Loader.image("myPic.jpg")
proxyImage.bind(on_load=self._image_loaded) self.image
= Image() return self.image
TestApp().run()
property loading_image
Image used for loading. You can change it by doing:
Loader.loading_image = 'loading.png'
property max_upload_per_frame
The number of images to upload per frame. By default, we’ll upload only 2 images to the GPU
per frame. If you are uploading many small images, you can easily increase this parameter to 10
or more. If you are loading multiple full HD images, the upload time may have consequences
and block the application. If you want a smooth experience, use the default.
As a matter of fact, a Full-HD RGB image will take ~6MB in memory, so it may take time. If you
have activated mipmap=True too, then the GPU must calculate the mipmap of these big images
too, in real time. Then it may be best to reduce the max_upload_per_frame to 1 or 2. If you
want to get rid of that (or reduce it a lot), take a look at the DDS format.
property num_workers
Number of workers to use while loading (used only if the loader implementation supports it).
This setting impacts the loader only on initialization. Once the loader is started, the setting has
no impact:
The default value is 2 for giving a smooth user experience. You could increase the number of
workers, then all the images will be loaded faster, but the user will not been able to use the
application while loading. Prior to 1.6.0, the default number was 20, and loading many full-hd
images was completely blocking the application.
pause()
Pause the loader, can be useful during interactions.
resume()
Resume the loader, after a pause().
run(*largs)
Main loop for the loader.
182
start()
Start the loader thread/process.
stop()
Stop the loader thread/process.
Properties
loaded: bool, defaults to False This value may be True if the image is already
cached.
Events
20.5 Atlas
Atlas manages texture atlases: packing multiple textures into one. With it, you reduce the number of
images loaded and speedup the application loading. This module contains both the Atlas class and
command line processing for creating an atlas from a set of individual PNG files. The command line section
requires the Pillow library, or the defunct Python Imaging Library (PIL), to be installed.
• a json file (.atlas) that contains the image file names and texture locations of the atlas.
• one or multiple image files containing textures referenced by the .atlas file.
{
"<basename>-<index>.png": {
"id1": [ <x>, <y>, <width>, <height> ], "id2": [ <x>, <y>
, <width>, <height> ],
#...
},
#...
}
{
"defaulttheme-0.png": {
"progressbar_background": [431, 224, 59, 24], "image-
missing": [253, 344, 48, 48], "filechooser_selected": [1, 207,
118, 118], "bubble_btn": [83, 174, 32, 32],
183
(continued from previous page)
In this example, “defaulttheme-0.png” is a large image, with the pixels in the rectangle from (431,
224) to (431 + 59, 224 + 24) usable as atlas://data/images/defaulttheme/ progressbar_background in
any image parameter.
Warning: The atlas creation requires the Pillow library (or the defunct Imaging/PIL library). This
requirement will be removed in the future when the Kivy core Image is able to support loading, blitting,
and saving operations.
You can directly use this module to create atlas files with this command:
Let’s say you have a list of images that you want to put into an Atlas. The directory is named images with
lots of 64x64 png files inside:
$ ls
images
$ cd images
$ ls
bubble.png bubble-red.png button.png button-down.png
You can combine all the png’s into one and generate the atlas file with:
As you can see, we get 2 new files: myatlas.atlas and myatlas-0.png. myatlas-0.png is a new
256x256 .png composed of all your images. If the size you specify is not large enough to fit all of the
source images, more atlas images will be created as required e.g. myatlas-1.png, myatlas-2.png etc.
Note: When using this script, the ids referenced in the atlas are the base names of the images without the
extension. So, if you are going to name a file ../images/button.png, the id for this image will be button.
If you need path information included, you should include use_path as follows:
184
20.5.3 How to use an Atlas
a = Button(background_normal='images/button.png',
background_down='images/button_down.png')
In our previous example, we have created the atlas containing both images and put them in images/
myatlas.atlas. You can use url notation to reference them:
a = Button(background_normal='atlas://images/myatlas/button',
background_down='atlas://images/myatlas/button_down')
atlas://path/to/myatlas/id
# will search for the ``path/to/myatlas.atlas`` and get the image ``id``
Note: In the atlas url, there is no need to add the .atlas extension. It will be automatically append to the
filename.
class kivy.atlas.Atlas(filename)
Bases: kivy.event.EventDispatcher
Manage texture atlas. See module documentation for more information.
Parameters
outname: str Basename to use for .atlas creation and -<idx>.png associ-
ated images.
185
use_path: bool, defaults to False If True, the relative path of the source png file
names will be included in the atlas ids rather that just in the file names.
Leading dots and slashes will be excluded and all other slashes in the path
will be replaced with underscores. For example, if use_path is False (the
default) and the file name is ../data/tiles/green_grass.png, the id will be
green_grass. If use_path is True, it will be data_tiles_green_grass.
Changed in version 1.8.0: Parameter use_path added
filename
Filename of the current Atlas.
textures
List of available textures within the atlas.
The cache manager can be used to store python objects attached to a unique key. The cache can be
controlled in two ways: with a object limit or a timeout.
For example, we can create a new cache with a limit of 10 objects and a timeout of 5 seconds:
If the instance is NULL, the cache may have trashed it because you’ve not used the label for 5 seconds and
you’ve reach the limit.
class kivy.cache.Cache
Bases: builtins.object
See module documentation for more information.
Parameters
186
timeout: double (optional) Time after which to delete the object if it has not
been used. If None, no timeout is applied.
Parameters
Parameters
Parameters
static print_usage()
Print the cache usage to the console.
Parameters
limit: int (optional) Maximum number of objects allowed in the cache. If None,
no limit is applied.
timeout: double (optional) Time after which to delete the object if it has not
been used. If None, no timeout is applied.
Parameters
key: str (optional) Unique identifier of the object in the store. If this argument
is not supplied, the entire category will be purged.
187
20.7 Clock object
The Clock object allows you to schedule a function call in the future; once or repeatedly at specified
intervals. You can get the time elapsed between the scheduling and the calling of the callback via the dt
argument:
# dt means delta-time
def my_callback(dt): pass
Note: If the callback returns False, the schedule will be canceled and won’t repeat.
If you want to schedule a function to call with default arguments, you can use the functools.partial python
module:
Conversely, if you want to schedule a function that doesn’t accept the dt argument, you can use a lambda
expression to write a short function that does accept dt. For Example:
def no_args_func():
print("I accept no arguments, so don't schedule me in the clock")
Note: You cannot unschedule an anonymous function unless you keep a reference to it. It’s better to add
*args to your function definition so that it can be called with an arbitrary number of parameters.
Important: The class method callback is weak-referenced: you are responsible for keeping a reference to
your original object/callback. If you don’t keep a reference, the ClockBase will never execute your callback.
For example:
class Foo(object):
def start(self):
Clock.schedule_interval(self.callback, 0.5)
188
(continued from previous page)
print('In callback')
foo.start()
Sometimes you need to schedule a callback BEFORE the next frame. Starting from 1.0.5, you can use a
timeout of -1:
The Clock will execute all the callbacks with a timeout of -1 before the next frame even if you add a new
callback with -1 from a running callback. However, Clock has an iteration limit for these callbacks: it
defaults to 10.
If you schedule a callback that schedules a callback that schedules a . . . etc more than 10 times, it will
leave the loop and send a warning to the console, then continue after the next frame. This is
implemented to prevent bugs from hanging or crashing the application.
If you need to increase the limit, set the max_iteration property:
# will run the callback twice before the next frame Clock.
schedule_once(my_callback) Clock.schedule_once(my_callback)
# will run the callback once before the next frame event =
Clock.create_trigger(my_callback)
event()
(continues on next page)
189
(continued from previous page)
event()
# will also run the callback only once before the next frame event = Clock.
schedule_once(my_callback) event() # now it's already scheduled
# won't be scheduled again
event()
In addition, it is more convenient to create and bind to the triggered event than using CyClockBase.
schedule_once() in a function:
class Sample(Widget):
def __init__(self, self. * *kwargs):
_trigger = Clock.create_trigger(self.cb) self).__init__
super(Sample, (**kwargs)
self.bind(x=self._trigger, y=self._trigger)
Even if x and y changes within one frame, the callback is only run once.
20.7.3 Unscheduling
190
is passed to CyClockBase.unschedule(), it’ll unschedule all instances of that callback (provided all is
True, the default, otherwise only the first match is removed).
Calling CyClockBase.unschedule() on the original callback is highly discouraged because it’s
significantly slower than when using the event.
Kivy’s clock has a lifecycle. By default, scheduling a callback after the Clock has ended will not raise an
error, even though the callback may never be called. That’s because most callbacks are like services, e.g.
responding to a user button press - if the app is running the callbacks need to service the app and respond
to the input, but once the app has stopped or is stopping, we can safely not process these events.
Other events always need to be processed. E.g. another thread may request a callback in kivy’s thread and
then process some result. If the event is not processed in Kivy’s thread because the app stopped, the
second thread may block forever hanging the application as it exits.
Kivy provides a exception handling manager, ExceptionManager, to handle its internal exceptions
including exceptions raised by clock callbacks, without crashing the application. By default when an
exception is raised, the app will crash. But, if a handler is registered with the exception manager and the
handler handles the exception, the app will not crash and will continue as normal.:
ExceptionManager.add_handler(MyHandler())
Then, all ValueError exceptions will be logged to the console and ignored. Similarly, if a scheduled clock
callback raises a ValueError, other clock events will still be processed normally.
191
If an event’s callback raises an exception, before the exception handler is executed, the callback is
immediately canceled.
It still is possible for the app to be corrupted if kivy itself is the source of the exception. I.e. even with a
handler that ignores exceptions and doesn’t crash, the app may be in a corrupted state if the error
originates from within Kivy itself. However, the exception handler can help protect the app from crashing
and can help protect against user callbacks crashing the app.
Changed in version 2.0.0: Prior to Kivy 2.0.0, an exception raised in a event’s callback would cause the clock
to crash and subsequent events may or may not be executed. Even if the exception was handled by an
ExceptionHandler, there was no guarantee that some scheduled events would not be skipped.
From 2.0.0 onward, if a event’s exception is handled by an ExceptionHandler, other events will be shielded
from the exception and will execute normally.
It is not safe to schedule Clock events from a object’s __del__ or __dealloc__ method. If you must
schedule a Clock call from this method, use CyClockBase.schedule_del_safe() or
CyClockBase.schedule_lifecycle_aware_del_safe() instead.
Beginning with 1.10.0, all the events scheduled for the same frame, e.g. all the events scheduled in the
same frame with a timeout of 0, well be executed in the order they were scheduled.
Also, all the scheduling and canceling methods are fully thread safe and can be safely used from external
threads.
The following section goes into the internal kivy clock details as well as the various clock options. It is
meant only for advanced users.
Fundamentally, the Kivy clock attempts to execute any scheduled callback rhythmically as determined by
the specified fps (frame per second, see maxfps in config). That is, ideally, given e.g. a desired fps of 30,
the clock will execute the callbacks at intervals of 1 / 30 seconds, or every 33.33 ms. All the callbacks in a
frame are given the same timestamp, i.e. the dt passed to the callback are all the same and it’s the
difference in time between the start of this and the previous frame.
Because of inherent indeterminism, the frames do not actually occur exactly at intervals of the fps and dt
may be under or over the desired fps. Also, once the timeout is “close enough” to the desired timeout, as
determined internally, Kivy will execute the callback in the current frame even when the “actual time” has
not elapsed the timeout amount.
Kivy offers now, since 1.10.0, multiple clocks with different behaviors.
192
Default Clock
The default clock (default) behaves as described above. When a callback with a timeout of zero or non-zero
is scheduled, they are executed at the frame that is near the timeout, which is a function of the fps. So a
timeout of zero would still result in a delay of one frame or about 1 / fps, typically a bit less but sometimes
more depending on the CPU usage of the other events scheduled for that frame.
In a test using a fps of 30, a callback with a timeout of 0, 0.001, and 0.05, resulted in a mean callback delay
of 0.02487, 0.02488, and 0.05011 seconds, respectively. When tested with a fps of 600 the delay for 0.05
was similar, except the standard deviation was reduced resulting in overall better accuracy.
Interruptible Clock
The default clock suffers from the quantization problem, as frames occur only on intervals and any
scheduled timeouts will not be able to occur during an interval. For example, with the timeout of 0.05,
while the mean was 0.05011, its values ranged between 0.02548 - 0.07348 and a standard deviation of
0.002. Also, there’s the minimum timeout of about 0.02487.
The interruptible clock (interrupt) will execute timeouts even during a frame. So a timeout of zero will
execute as quickly as possible and similarly a non-zero timeout will be executed even during the interval.
This clock, and all the clocks described after this have an option, ClockBaseInterruptBehavior.
interupt_next_only. When True, any of the behavior new behavior will only apply to the callbacks with
a timeout of zero. Non-zero timeouts will behave like in the default clock. E.g. for this clock when
True, only zero timeouts will execute during the the interval.
In a test using a fps of 30, a callback with a timeout of 0, 0.001, and 0.05, resulted in a mean callback
delay of 0.00013, 0.00013, and 0.04120 seconds, respectively when ClockBaseInterruptBehavior.
interupt_next_only was False. Also, compared to the default clock the standard deviation was
reduced. When ClockBaseInterruptBehavior.interupt_next_only was True, the values were 0.00010,
0.02414, and 0.05034, respectively.
Free Clock
The interruptible clock may not be ideal for all cases because all the events are executed during the
intervals and events are not executed anymore rhythmically as multiples of the fps. For example, there
may not be any benefit for the graphics to update in a sub-interval, so the additional accuracy wastes CPU.
The Free clock (free_all) solves this by having Clock.xxx_free versions of all the Clock scheduling
methods. By free, we mean the event is free from the fps because it’s not fps limited. E.g.
CyClockBaseFree.create_trigger_free() corresponds to CyClockBase.
create_trigger(). Only when an event scheduled using the Clock.xxx_free methods is present will the
clock interrupt and execute the events during the interval. So, if no free event is present the clock
behaves like the default clock, otherwise it behaves like the interrupt clock.
In a test using a fps of 30, a callback with a timeout of 0s, 0.001s, and 0.05s, resulted in a mean callback
delay of 0.00012s, 0.00017s, and 0.04121s seconds, respectively when it was a free event and 0.02403s,
0.02405s, and 0.04829s, respectively when it wasn’t.
193
Free Only Clock
The Free clock executes all events when a free event was scheduled. This results in normal events also
being execute in the middle of the interval when a free event is scheduled. For example, above, when a
free event was absent, a normal event with a 0.001s timeout was delayed for 0.02405s. However, if a free
event happened to be also scheduled, the normal event was only delayed 0.00014s, which may be
undesirable.
The Free only clock (free_only) solves it by only executing free events during the interval and normal events
are always executed like with the default clock. For example, in the presence of a free event, a normal
event with a timeout of 0.001s still had a delay of 0.02406. So this clock, treats free and normal events
independently, with normal events always being fps limited, but never the free events.
Summary
The kivy clock type to use can be set with the kivy_clock option the config. If KIVY_CLOCK is present in
the environment it overwrites the config selection. Its possible values are as follows:
• When kivy_clock is default, the normal clock, ClockBase, which limits callbacks to the maxfps
quantization - is used.
• When kivy_clock is interrupt, a interruptible clock, ClockBaseInterrupt, which doesn’t limit any
callbacks to the maxfps - is used. Callbacks will be executed at any time.
• When kivy_clock is free_all, a interruptible clock, ClockBaseFreeInterruptAll, which doesn’t limit
any callbacks to the maxfps in the presence of free events, but in their absence it limits events
to the fps quantization interval - is used.
• When kivy_clock is free_only, a interruptible clock, ClockBaseFreeInterruptAll, which treats free
and normal events independently; normal events are fps limited while free events are not - is
used.
Experimental async support has been added in 2.0.0. The Clock now has a ClockBaseBehavior.
async_tick() and ClockBaseBehavior.async_idle() coroutine method which is used by the kivy
EventLoop when the kivy EventLoop is executed in a asynchronous manner. When used, the kivy
clock does not block while idling.
The async library to use is selected with the KIVY_EVENTLOOP environmental variable or by calling
init_async_lib() directly. The library can be one of “asyncio” when the standard library asyncio should
be used, or “trio” if the trio library should be used. If not set it defaults to “asyncio”.
See app for example usage.
class kivy.clock.ClockBase(**kwargs)
Bases: kivy.clock.ClockBaseBehavior, kivy._clock.CyClockBase
The default kivy clock. See module for details.
usleep(microseconds)
Sleeps for the number of microseconds.
194
Traduit de Anglais vers Français - www.onlinedoctranslator.com
async_lib: chaîne de caractères La bibliothèque async à utiliser lorsque l'horloge est exécutée de manière asynchrone.
Peut être l'un des, "asyncio" quand la bibliothèque standard asyncio doit être utilisée, ou
"trio" si la bibliothèque trio doit être utilisée.
MIN_SOMMEIL = 0,005
Le temps minimum pour dormir. Si le temps restant est inférieur à cela, la boucle d'événements continuera.
async async_idle()
version asynchrone (interne) de inactif().
async async_tick()
version asynchrone de cocher().
cadres de propriété
Nombre d'images internes (pas nécessairement dessinées) depuis le début de l'horloge.
propriété frames_displayed
Nombre d'images affichées depuis le début de l'horloge.
durée de la propriété
Temps passé entre la dernière image et l'image actuelle (en secondes).
get_boottime()
Obtenez le temps en secondes depuis le démarrage de l'application.
get_fps()
Obtenez le FPS moyen actuel calculé par l'horloge.
get_rfps()
Obtenez le FPS "réel" actuel calculé par l'horloge. Ce compteur reflète la fréquence d'images
réelle affichée à l'écran.
Contrairement à get_fps(), cette fonction renvoie un compteur du nombre d'images, pas la moyenne
des images par seconde.
obtenir du temps()
inactif()
(interne) attend ici jusqu'à la prochaine image.
init_async_lib(lib)
Définit manuellement la bibliothèque asynchrone à utiliser en interne, lors de l'exécution de manière asynchrone.
Cela peut être appelé à tout moment avant le début de la boucle d'événements kivy, mais pas une fois que l'application kivy est en cours
d'exécution.
Paramètres
lib: chaîne de caractères La bibliothèque async à utiliser lorsque l'horloge est exécutée de manière asynchrone. Pouvez
être l'un de, "asyncio" quand la bibliothèque standard asyncio doit être utilisée, ou "trio" si
la bibliothèque trio doit être utilisée.
195
post_idle(ts, courant)
Appelé après inactif() par cocher().
pre_idle()
Appelé avant inactif() par cocher().
cocher()
Avancez l'horloge à l'étape suivante. Doit être appelé à chaque trame. L'horloge par défaut a une fonction
tick() appelée par le framework Kivy de base.
tick_draw()
Cochez le compteur de dessins.
temps statique()
Méthode proxy pour horloge().
tu dors(microsecondes)
Dort pendant le nombre de microsecondes.
classer kivy.horloge.HorlogeBaseLibreInterruptionTous(**kwargs)
Bases : kivy.clock.ClockBaseInterruptFreeBehavior, kivy._clock.
CyClockBaseGratuit
le free_all horloge de Kivy. Voir module pour plus de détails.
classer kivy.horloge.ClockBaseFreeInterruptOnly(**kwargs)
Bases : kivy.clock.ClockBaseInterruptFreeBehavior, kivy._clock.
CyClockBaseGratuit
le gratuit_seulement horloge de Kivy. Voir module pour plus de détails.
async async_idle()
version asynchrone (interne) de inactif().
inactif()
(interne) attend ici jusqu'à la prochaine image.
async async_idle()
version asynchrone (interne) de inactif().
inactif()
(interne) attend ici jusqu'à la prochaine image.
init_async_lib(lib)
Définit manuellement la bibliothèque asynchrone à utiliser en interne, lors de l'exécution de manière asynchrone.
Cela peut être appelé à tout moment avant le début de la boucle d'événements kivy, mais pas une fois que l'application kivy est en cours
d'exécution.
Paramètres
lib: chaîne de caractères La bibliothèque async à utiliser lorsque l'horloge est exécutée de manière asynchrone. Pouvez
être l'un de, "asyncio" quand la bibliothèque standard asyncio doit être utilisée, ou "trio" si
la bibliothèque trio doit être utilisée.
tu dors(microsecondes)
Dort pendant le nombre de microsecondes.
196
classer kivy.horloge.HorlogeBaseInterruptionLibreComportement(**kwargs)
Bases : kivy.clock.ClockBaseInterruptBehavior
Une classe de base pour l'horloge qui interrompt l'intervalle de sommeil pour les événements gratuits.
classer kivy.horloge.HorlogeEvénement(Horloge CyClockBase, boucle int, rappeler, double délai d'attente, heure de démarrage double,
cid=Aucun, int trigger=Faux, clock_ended_callback=Aucun,
release_ref=Vrai, **kwargs)
Bases : Builtins.object
Cette classe n'est jamais créée par l'utilisateur ; à la place, kivy crée et renvoie une instance de cette classe lors de
la planification d'un rappel.
Un événement peut être déclenché (planifié) en l'appelant. Si c'est déjà programmé, rien ne se passera, sinon ce
sera programmé. Par exemple:
rappeler
rappel : objet
Annuler()
Annule le rappel s'il devait être appelé. S'il n'est pas programmé, rien ne se passe.
cid
cid : objet
horloge
horloge : kivy._clock.CyClockBase CyClockBase instance associée à l'événement.
clock_ended_callback
clock_ended_callback : objet Un rappel facultatif pour cet événement, qui, s'il est fourni, est appelé
par l'horloge
lorsque l'horloge est arrêtée et que l'événement n'a pas été coché.
get_callback()
Renvoie le rappel associé à l'événement. Les rappels sont stockés avec une référence indirecte afin de
ne pas garder les objets en vie. Si le rappel est mort, None est renvoyé.
get_clock_ended_callback()
Renvoie le clock_ended_callback associé à l'événement. Les rappels sont stockés avec une référence
indirecte afin de ne pas garder les objets en vie. Si le rappel est mort ou n'a pas été fourni, None est
renvoyé.
est déclenché
Renvoie si l'événement est programmé pour que son rappel soit exécuté par le thread kivy.
boucler
loop: 'int' Indique si cet événement se répète à des intervalles de temps libre.
suivant
suivant : kivy._clock.ClockEvent Le suivant HorlogeEvénement dans l'ordre où ils ont été programmés.
précédent
prev: kivy._clock.ClockEvent Le précédent HorlogeEvénement dans l'ordre où ils ont été programmés.
Libération()
(méthode interne) Convertit le rappel en une référence indirecte.
197
release_ref
release_ref : 'int' Si True, l'événement ne doit jamais libérer la référence aux rappels.
cocher(double court)
(méthode interne) Traite l'événement pour le thread kivy.
temps libre
timeout : 'double' La durée après la planification lorsque le rappel doit être exécuté.
faible_rappel
faible_callback : objet
faible_horloge_ended_callback
low_clock_ended_callback : objet
exception kivy.horloge.ClockNotRunningError
Bases : Erreur d'exécution
Levée par l'Horloge Kivy lors de la programmation d'un événement si l'Horloge Kivy est déjà terminée (
stop_horloge a été appelé).
classer kivy.horloge.CyClockBase(**kwargs)
Bases : Builtins.object
résolution_horloge
résolution_horloge : 'double' Si le temps restant jusqu'à l'expiration de l'événement est inférieur à
résolution_horloge,
l'horloge exécutera le rappel même s'il n'a pas exactement expiré.
Si -1, la valeur par défaut, la résolution sera calculée à partir de la configuration maxfps. Sinon, la valeur
fournie est utilisée. La valeur par défaut est -1.
Paramètres
intervalle: bool Si le rappel doit être appelé une fois (False) ou plusieurs fois
avec une période de temps libre (Vrai) comme schedule_interval().
198
release_ref : bobo Si Vrai, la défaut, ensuite si rappeler ou
clock_ended_callback est une méthode de classe et l'objet n'a aucune
référence à elle, alors l'objet peut être ramassé et les rappels ne seront pas
appelés. Si False, l'horloge conserve une référence à l'objet l'empêchant
d'être ramassée - elle sera donc appelée.
Retour UNE HorlogeEvénement exemple. Pour planifier le rappel de cette instance, vous pouvez
appeler.
Pour annuler l'événement avant qu'il ne soit exécuté, appelez ClockEvent.cancel() sur l'événement retourné. Pour le
programmer à nouveau, appelez simplement l'événement (un événement()) et il sera reprogrammé en toute sécurité s'il
n'est pas déjà programmé.
Paramètres
intervalle: bool Si le rappel doit être appelé une fois (False) ou plusieurs fois
avec une période de temps libre (Vrai) comme schedule_interval().
release_ref : bobo Si True, la valeur par défaut, alors si rappeler est une méthode de classe et
l'objet n'a aucune référence à lui, alors l'objet peut être récupéré et les
rappels ne seront pas appelés. Si False, l'horloge conserve une référence à
l'objet l'empêchant d'être ramassée - elle sera donc appelée.
Retour UNE HorlogeEvénement exemple. Pour planifier le rappel de cette instance, vous pouvez
appeler.
obtenir_événements()
Renvoie la liste des HorlogeEvénement instances actuellement planifiées.
get_min_timeout()
Renvoie le temps restant depuis le début de l'image actuelle pour l'événement avec le plus petit délai
d'attente.
obtenir_résolution()
Renvoie la résolution minimale de l'horloge. C'est une fonction derésolution_horloge et
maxfps fourni à la config.
handle_exception(e)
Fournit une opportunité de gérer l'exception d'un événement.
Si vous le souhaitez, l'exception est gérée, sinon elle doit être déclenchée à nouveau. Par défaut, il est à nouveau
levé.
199
Paramètres e – L'exception à gérer.
Nouveau dans la version 2.0.0.
a fini
has_ended : 'int'
itération_max
max_iteration: 'int' Le nombre maximum d'itérations de rappel à la fin de la trame, avant la
suivante
Cadre. Si plusieurs itérations se produisent, un avertissement est émis.
on_planning(un événement)
Fonction qui est appelée en interne chaque fois qu'un événement est déclenché pour cette horloge. Il prend l'événement
comme paramètre.
L'ordre de on_planning les appels ne sont pas garantis d'être dans le même ordre que les événements sont
programmés. De même, il est possible que l'événement en cours de programmation ait été annulé avant que celui-
ci ne soit appelé sur l'événement. C'est parce queon_schedule() peut être appelé à partir de différents threads.
schedule_del_safe(rappeler)
Planifiez un rappel qui est thread-safe et __del__ ou __dealloc__ en sécurité.
Il n'est pas sûr d'appeler différents types de code à partir de __del__ ou __dealloc__ méthodes car elles
peuvent être exécutées à tout moment. La plupart des méthodes d'horloge de Kivy ne sont pas sûres pour
appeler l'horloge à partir de ces méthodes. Au lieu de cela, utilisez cette méthode, qui est thread-safe et __
del__ ou __dealloc__ safe, pour programmer le rappel dans le thread kivy. Il sera exécuté dans l'ordre après
le traitement des événements normaux.
Paramètres
Pour annuler l'événement avant qu'il ne soit exécuté, appelez ClockEvent.cancel() sur l'événement
retourné. Si le rappel est une méthode de classe, une référence faible à l'objet est créée et elle peut être
récupérée s'il n'y a pas d'autre référence à l'objet.
schedule_lifecycle_aware_del_safe(rappeler, clock_ended_callback)
Planifiez un rappel qui est thread-safe et __del__ ou __dealloc__ sûr de la même manière que
schedule_del_safe(), mais le rappel est sensible à l'état de l'horloge.
Si cet événement est déclenché après l'arrêt de l'horloge (stop_horloge()), puis un
ClockNotRunningError sera élevé. Si l'erreur n'est pas levée, alors soitrappeler ou
clock_ended_callback sera appelé. rappeler sera appelé lorsque le rappel sera exécuté
normalement. Si l'horloge est arrêtée avant de pouvoir être exécutée, à condition que
l'application s'est fermée normalement sans planter, alorsclock_ended_callback sera appelé à la
place lorsque l'horloge est arrêtée.
Paramètres
200
clock_ended_callback: appelable Un rappel qui sera appelé si l'horloge est
arrêté alors que le rappel est toujours programmé pour être appelé. Le rappel
prend un seul paramètre - le rappel. Si l'application s'est fermée normalement, il
est garanti que soitrappeler ou clock_ended_callback aurait été appelé.
Pour annuler l'événement avant qu'il ne soit exécuté, appelez ClockEvent.cancel() sur l'événement
retourné. Si le rappel est une méthode de classe, une référence faible à l'objet est créée et elle peut être
récupérée s'il n'y a pas d'autre référence à l'objet.
Modifié dans la version 1.0.5 : Si le timeout est de -1, le rappel sera appelé avant la prochaine trame (à
tick_draw()).
start_clock()
Doit être appelé pour démarrer l'horloge.
stop_horloge()
Arrête l'horloge et nettoie.
Cela doit être appelé pour traiter les rappels lifecycle_aware, etc.
imprévu(rappeler, tout=vrai)
Supprimer un événement précédemment programmé.
Paramètres
tout: bool Si vrai et si rappeler est un appelable, toutes les instances de cet appelable seront
non planifié (c'est-à-dire si cet appelable a été planifié plusieurs fois). Par défaut à Vrai
.
Modifié dans la version 1.9.0 : Le paramètre all a été ajouté. Avant, il se comportait comme sitout a été Vrai.
classer kivy.horloge.CyClockBaseGratuit
Bases : kivy._clock.CyClockBase
Une classe d'horloge qui prend en charge la planification d'événements gratuits en plus des événements normaux.
201
create_lifecycle_aware_trigger_free(rappeler, clock_ended_callback, délai d'attente=0,
intervalle=Faux, release_ref=Vrai) →
FreeClockEvénement
Semblable à create_lifecycle_aware_trigger(), mais crée à la place un événement gratuit.
get_min_free_timeout()
Renvoie le temps restant depuis le début de l'image actuelle pour le gratuit événement avec le plus petit
délai d'attente.
gratuit
free : 'int' Indique si cet événement a été planifié comme un événement gratuit.
kivy.horloge.fil principal(fonction)
Décorateur qui planifiera l'appel de la fonction pour la prochaine trame disponible dans le thread principal. Cela peut être
utile lorsque vous utilisezUrlRequête ou lorsque vous programmez des threads : vous ne pouvez effectuer aucun travail
lié à OpenGL dans un thread.
Veuillez noter que cette méthode retournera directement et qu'aucun résultat ne pourra être retourné :
@mainthread
déf rappeler(soi, *arguments): imprimer(« La
demande a réussi ! »,
'Ce rappel est appelé dans le thread principal.')
Ce module fournit un ensemble de types et de fonctions d'utilitaires pour l'optimisation et pour aider à l'écriture de code
compatible Python 2/3.
kivy.compat.PY2 = Faux
Faux, car nous ne prenons plus en charge Python 2.
kivy.compat.horloge() → flavoine
Une horloge avec la résolution la plus élevée disponible sur votre système d'exploitation actuel.
202
rel_tol différence maximale pour être considérée comme « proche », par rapport à l'ampleur de
les valeurs d'entrée
abs_tol différence maximale pour être considéré comme « proche », quelle que soit l'ampleur
des valeurs d'entrée
Pour que les valeurs soient considérées comme proches, la différence entre elles doit être inférieure à au moins
une des tolérances.
- inf, inf et NaN se comportent de manière similaire à la norme IEEE 754. C'est-à-dire que NaN n'est proche de rien, même
de lui-même. inf et -inf ne sont proches que d'eux-mêmes.
kivy.compat.string_types
alias de str
le Configuration object est une instance d'un Python ConfigParser modifié. Voir leDocumentation ConfigParser
pour plus d'informations.
Kivy a un fichier de configuration qui détermine les paramètres par défaut. Afin de modifier ces paramètres, vous pouvez
modifier ce fichier manuellement ou utiliser l'objet Config. S'il vous plaît voir leConfigurer Kivy rubrique pour plus
d'informations.
Les options de configuration contrôlent l'initialisation du Application. Afin d'éviter les situations où les paramètres de
configuration ne fonctionnent pas ou ne sont pas appliqués avant la création de la fenêtre (comme la définition d'une
taille de fenêtre initiale), Config.set doit être utilisé avant d'importer d'autres modules Kivy. Idéalement, cela signifie les
définir dès le début de votre script main.py.
Alternativement, vous pouvez enregistrer ces paramètres de manière permanente en utilisant Config.set ensuite Config.écriture. Dans
ce cas, vous devrez redémarrer l'application pour que les modifications prennent effet. Notez que cette approche affectera toutes les
applications Kivy à l'échelle du système.
Veuillez noter qu'aucun trait de soulignement (_) sont autorisés dans le nom de la section.
Pour plus d'informations sur la configuration de votre Application, veuillez consulter le Paramétrage des applications section.
Modifié dans la version 1.7.1 : Le ConfigParser devrait maintenant fonctionner correctement avec utf-8. Les valeurs sont
converties d'ascii en unicode uniquement lorsque cela est nécessaire. La méthode get() renvoie des chaînes utf-8.
203
20.9.3 Modification de la configuration avec des variables d'environnement
Depuis la 1.11.0, il est désormais possible de modifier la configuration à l'aide de variables d'environnement. Ils sont
prioritaires sur le config.ini chargé. Le format est :
KCFG_<section>_<clé> = <valeur>
Par example:
KCFG_GRAPHICS_FULLSCREEN=auto . . . KCFG_KIVY_LOG_LEVEL=avertissement . . .
Ou dans votre dossier avant tout import kivy :
Si vous ne souhaitez mapper aucune variable d'environnement, vous pouvez désactiver le comportement :
kivy
police par défaut: liste Polices par défaut utilisées pour les widgets affichant n'importe quel texte. Il dé-
défauts à ['Roboto', 'data/fonts/Roboto-Regular.ttf', 'data/fonts/Roboto-Italic.ttf',
'data/fonts/Roboto-Bold.ttf', 'data/fonts/Roboto- BoldItalic.ttf'].
bureau: entier, 0 ou 1 Cette option contrôle les fonctionnalités spécifiques du système d'exploitation de bureau, telles que l'activation
barre de défilement pouvant être déplacée dans les vues de défilement, désactivation des bulles dans TextInput, etc. 0 est
exit_on_escape: entier, 0 ou 1 Permet de quitter Kivy lorsque l'échappement est enfoncé. 0 est désactivé,
1 est activé.
pause_on_minimize: entier, 0 ou 1 Si réglé sur 1, la boucle principale est interrompue et le on_pause
L'événement est distribué lorsque la fenêtre est réduite. Cette option est destinée à une utilisation sur le
bureau uniquement. Par défaut à0.
mode_clavier: chaîne de caractères Spécifie le mode clavier à utiliser. Si peut être l'un des
beuglant :
• '' - Laissez Kivy choisir la meilleure option pour votre plateforme actuelle.
log_enable: entier, 0 ou 1 Activez la journalisation des fichiers. 0 est désactivé, 1 est activé.
log_level: chaîne, l'un des 'trace', 'debug', 'info', 'warning', 'error' ou 'critical' Met le
niveau de journalisation minimum à utiliser.
nom_journal: chaîne de caractères Chaîne de format à utiliser pour le nom de fichier du fichier journal.
204
log_maxfiles: entier Conservez les fichiers journaux récents de log_maxfiles tout en purgeant le répertoire des journaux. Ensemble
'log_maxfiles' à -1 pour désactiver la purge des fichiers journaux (par exemple, conserver tous les fichiers journaux).
Noter: Vous vous retrouvez avec des fichiers journaux 'log_maxfiles + 1' car l'enregistreur en ajoute un
nouveau après la purge.
icône_fenêtre: chaîne de caractères Chemin de l'icône de la fenêtre. Utilisez-le si vous souhaitez remplacer le
icône pygame par défaut.
postproc
ignorer: liste de tuples Liste des régions où les nouvelles touches sont ignorées. Cette configuration
Le jeton peut être utilisé pour résoudre les problèmes de hotspot avec du matériel DIY. Le format de la
liste doit être :
jitter_distance: entier Distance maximale pour la détection de gigue, normalisée à l'intérieur de la plage
0 - 1000.
jitter_ignore_devices: chaîne, séparée par des virgules Liste des appareils à ignorer
détection de gigue.
conserver_distance: entier Si le toucher se déplace plus que ce qui est indiqué par keep_distance, il
ne sera pas retenu. L'argument doit être un entier compris entre 0 et 1000.
graphique
sans frontières: int, un de 0 ou 1 Si réglé sur 1, supprime la bordure/la décoration de la fenêtre. Gagner-
dow redimensionnement doit également être désactivé pour masquer la bordure de redimensionnement.
fbo: chaîne, l'un des 'hardware', 'software' ou 'force-hardware' Sélectionne le retour FBO-
fin à utiliser.
plein écran: int ou string, l'un des 0, 1, 'fake' ou 'auto' Activer le plein écran. Si réglé sur1, une
Resolution de largeur fois la taille pixels seront utilisés. Si réglé surauto, la résolution de votre
écran actuel sera utilisée à la place. C'est probablement ce que vous voulez. Si vous
205
voulez placer la fenêtre dans un autre affichage, utilisez faux, ou définissez le sans frontières option de
la section graphique, puis ajustez largeur, la taille, Haut et à gauche.
la taille: entier Hauteur de la Fenêtre, pas utilisé si plein écran est réglé sur auto.
Noter: Cette fonctionnalité est limitée par la prise en charge matérielle du périphérique et n'aura aucun effet sur les
périphériques qui ne prennent pas en charge le niveau de MSAA demandé.
position: chaîne, l'un des 'auto' ou 'custom' Position de la fenêtre sur votre écran. Si
auto est utilisé, vous n'avez aucun contrôle sur la position initiale : Haut et à gauche sont ignorés.
largeur: entier Largeur de la Fenêtre, pas utilisé si plein écran est réglé sur auto.
min_state_time: flottant, la valeur par défaut est .035 Temps minimum pour que les widgets affichent un
état visuel. Cet attribut est actuellement utilisé par des widgets commeMenu déroulant &
Comportement des boutons pour s'assurer qu'ils affichent leur état visuel actuel pour le temps
donné.
vsync: rien, valeur vide ou entiers Si vsync est activé, actuellement uniquement utilisé
avec fenêtre sdl2. Les valeurs possibles sontrien ou valeur vide - la laisse inchangée, 0 -
désactive vsync, 1 ou plus grand - définit l'intervalle vsync, -1 définit la synchronisation
adaptative. Il retombe à 1 si le réglage est2+ ou -1 manqué. VoirSDL_GL_SetSwapInterval.
verify_gl_main_thread: int, 1 ou 0, par défaut à 1 S'il faut vérifier si le code qui change
toutes les instructions gl s'exécutent en dehors du thread principal, puis génèrent une erreur.
saisir Vous pouvez créer de nouveaux périphériques d'entrée en utilisant cette syntaxe :
206
Voir également:
Vérifiez les fournisseurs dans kivy.input.fournisseurs pour la syntaxe à utiliser dans le fichier de
configuration.
widgets
nommodule =
Tout ce qui se trouve après le = sera transmis au module en tant qu'arguments. Consultez la documentation
du module spécifique pour une liste des arguments acceptés.
Modifié dans la version 2.1.0 : vsync a été ajouté à la section graphique. verify_gl_main_thread a été ajouté
à la section graphique.
Modifié dans la version 1.10.0 : min_state_time et allow_screensaver ont été ajoutés au graphique section.
kivy_clock a été ajouté à la section kivy. police par défaut a été ajouté à la section kivy.
Modifié dans la version 1.9.0 : sans frontières et état_fenêtre ont été ajoutés à la section graphique. lefaux
réglage de la plein écran l'option a été dépréciée, utilisez le sans frontières option à la place. pause_on_minimize
a été ajouté à la section kivy.
Modifié dans la version 1.8.0 : systemanddock et systemandmulti a été ajoutée comme valeurs possibles pour
mode_clavier dans la section Kivy. exit_on_escape a été ajouté à la section kivy.
Modifié dans la version 1.1.0 : tuio n'écoute plus par défaut. Les icônes de fenêtre ne sont plus copiées dans le répertoire utilisateur. Vous
pouvez toujours définir une nouvelle icône de fenêtre en utilisant leicône_fenêtre paramètre de configuration.
Modifié dans la version 1.0.8 : scroll_timeout, scroll_distance et scroll_friction ont été ajoutés.
list_friction, list_trigger_distance et list_friction_bound ont été supprimés. type_clavier et clavier ont
été supprimés du widget. mode_clavier et clavier ont été ajoutés à la section kivy.
kivy.config.Configuration = Aucune
L'objet de configuration Kivy par défaut. C'est unConfigParser exemple avec le Nom réglé sur
« kivy ».
Configuration = ConfigParser(Nom='kivy')
207
Classe ConfigParser améliorée qui prend en charge l'ajout de sections et de valeurs par défaut.
Par défaut, l'instance kivy ConfigParser, Configuration, est appelé 'kivy' et l'instance ConfigParser utilisée
par le App.build_settings la méthode est nommée 'application'.
Paramètres
Modifié dans la version 1.9.0 : chaque ConfigParser peut désormais être nommé. Vous pouvez obtenir le
ConfigParser associé à un nom en utilisantget_configparser(). De plus, vous pouvez maintenant contrôler les
valeurs de configuration avecConfigParserProperty.
Si v̀ars' est fourni, il doit s'agir d'un dictionnaire. L'option est recherchée dans v̀ars' (si elle est fournie),
section', et dans D̀EFAULTSECT' dans cet ordre. Si la clé n'est pas trouvée et`fallback' est fourni, il est
utilisé comme valeur de secours. « un » peut être fourni en tant que`valeur de repli.
Si l'interpolation est activée et l'argument optionnel `raw' est False, toutes les interpolations sont
développées dans les valeurs de retour.
get_configparser statique(Nom)
Renvoie le ConfigParser instance dont le nom est Nom, ou Aucun s'il n'est pas trouvé.
Paramètres
nom de la propriété
Le nom associé à cette instance ConfigParser, sinon ''. Par défaut à''. Il peut être modifié en toute sécurité de
manière dynamique ou défini sur''.
Lorsqu'un ConfigParser reçoit un nom, cet objet de configuration peut être récupéré en utilisant
get_configparser(). De plus, cette instance de configuration peut également être utilisée avec un
ConfigParserProperty instance qui a défini son configuration valeur à ce nom.
Définir plus d'un ConfigParser avec le même nom augmentera Erreur de valeur.
208
lire(nom de fichier)
Lire un seul nom de fichier. Contrairement au ConfigParser original de Python, celui-ci est capable de
lire un seul fichier à la fois. Le dernier fichier lu sera utilisé pour leécrivez() méthode.
Modifié dans la version 1.9.0 : lire() appelle maintenant les rappels si read a changé des valeurs.
Définissez plusieurs valeurs-clés par défaut dans une section. keyvalues doit être un dictionnaire contenant les
nouvelles valeurs par défaut.
écrivez()
Écrivez la configuration dans le dernier fichier ouvert à l'aide de la lire() méthode.
20.10 Contexte
Avertissement: Ceci est expérimental et sujet à changement tant que cet avertissement est présent.
Kivy a quelques instances « globales » qui sont utilisées directement par de nombreux éléments du framework : Cacher, Constructeur, Horloge.
kivy.context.get_current_context()
Renvoie le contexte actuel.
209
20.11 Répartiteur d'événements
Tous les objets qui produisent des événements dans Kivy implémentent le Répartiteur d'événements qui fournit une interface cohérente pour
l'enregistrement et la manipulation des gestionnaires d'événements.
Modifié dans la version 1.0.9 : la découverte de propriétés et les méthodes ont été déplacées de la Widget à la
Répartiteur d'événements.
appliquer_propriété(**kwargs)
Ajoute des propriétés au moment de l'exécution à la classe. La fonction accepte les arguments mot-
clé de la formeprop_name=prop, où soutenir est un Propriété exemple et prop_name est le nom de
l'attribut de la propriété.
Avertissement: Cette méthode n'est pas recommandée pour un usage courant car vous devez déclarer
les propriétés dans votre classe au lieu d'utiliser cette méthode.
Par example:
lier(**kwargs)
Liez un type d'événement ou une propriété à un rappel.
Usage:
# Avec Propriétés
déf my_x_callback(obj, valeur):
imprimer('sur objet', obj, 'x changé en', valeur)
déf my_width_callback(obj, valeur):
imprimer('sur objet', obj, 'largeur changée en', valeur) soi.lier(X=
my_x_callback, largeur=my_width_callback)
# Avec un événement
déf my_press_callback(obj): imprimer(
'événement sur objet', obj) soi.lier(on_press=
my_press_callback)
En général, les rappels de propriété sont appelés avec 2 arguments (l'objet et la nouvelle valeur de la
propriété) et les rappels d'événement avec un argument (l'objet). L'exemple ci-dessus illustre cela.
L'exemple suivant montre différentes manières d'utiliser la fonction bind dans une application
complète :
210
(suite de la page précédente)
classer DemoBox(BoxLayout):
"""
Cette classe démontre diverses techniques qui peuvent être utilisées
??
→ pour lier à
événements. Bien que les pièces puissent être rendues plus optimales, avancées
??
→ Concepts Python
sont évités pour des raisons de lisibilité et de clarté. """
# Vous pouvez également déclarer une fonction qui accepte une variable de
??
→ numéro
# arguments positionnels et mots-clés et utiliser l'introspection
??
→ à déterminer
# ce qui est transmis. C'est très pratique pour
→ débogage aussi
??
# Enfin, nous montrons comment utiliser les fonctions partielles. Ils sont
??
→ parfois
# difficile à saisir, mais offre une
??
→ moyen puissant de
(suite à la page suivante)
211
(suite de la page précédente)
# fonctions de réutilisation.
btn5 = Bouton(texte="En utilisant des fonctions partielles. Pour les inconditionnels.
??
→ ")
btn5.lier(on_press=partiel(soi.sur_n'importe quoi, "1", "2",
??
→ mensuel="python"))
classer DemoApp(Application):
déf construire(soi):
retourner DemoBox()
si __Nom__ == "__principale__":
DemoApp().Cours()
Si un rappel a déjà été lié à un événement ou à une propriété donnée, il ne sera plus ajouté.
La première est que la liaison n'empêchera pas le ramasse-miettes de l'objet de la méthode. Le client
doit conserver une référence à l'instance pour la durée de vie souhaitée. La référence de rappel est
supprimée en silence si elle devient invalide.
La seconde est que lorsque vous utilisez une méthode décorée, par exemple :
@mon_décorateur
déf rappeler(soi, passe * arguments):
Modifié dans la version 1.8.0 : valeur paramètre ajouté, peut être utilisé pour définir la valeur par défaut de
la propriété. De plus, le type de la valeur est utilisé pour spécialiser la propriété créée.
Modifié dans la version 1.9.0 : dans le passé, si valeur était du type bobo, une Propriété numérique serait créé,
maintenant un Propriété booléenne est créé.
De plus, les arguments now et positionnels et les mots-clés sont transmis à la propriété lors de sa création.
212
Modifié dans la version 2.0.0 : default_value a été ajouté.
Avertissement: Cette fonction est conçue pour le langage Kivy, ne l'utilisez pas dans votre code. Vous
devez déclarer la propriété dans votre classe au lieu d'utiliser cette méthode.
Paramètres
valeur: objet, facultatif Valeur par défaut de la propriété. Le type est également utilisé pour la création
types de propriété plus appropriés. La valeur par défaut est Aucun.
valeur par défaut: bool, True par défaut Si vrai, valeur sera la valeur par défaut pour le
propriété. Sinon, la propriété sera initialisée avec la valeur par défaut
normale du type de propriété, puis définie survaleur.
La fonction collecte tous les arguments de position et de mot-clé et les transmet aux
gestionnaires.
Noter: Les gestionnaires sont appelés dans l'ordre inverse de celui avec lequel ils ont été enregistrés lier().
Paramètres
Modifié dans la version 1.9.0 : la collecte et le transfert d'arguments de mots-clés ont été ajoutés.
Auparavant, seuls les arguments positionnels étaient collectés et transmis.
événements()
Retourne tous les événements de la classe. Peut être utilisé pour l'introspection.
1. Par opposition à lier(), il ne vérifie pas que cette fonction et largs/kwargs n'ont pas été liés
auparavant à ce nom. Donc, lier le même rappel plusieurs fois ne fera que continuer à
l'ajouter.
2. Bien que lier() crée un Méthode faible du rappel lors de la liaison à un événement ou à une propriété,
cette méthode stocke le rappel directement, à moins qu'un argument de mot-clé réf avec
213
la valeur True est fournie, puis un Méthode faible est enregistré. Ceci est utile lorsqu'il n'y a pas de
risque de fuite de mémoire en stockant directement le rappel.
3. Cette méthode renvoie un nombre positif unique si Nom a été trouvé et lié, et 0, autrement.
Il ne soulève pas d'exception, commelier() si la propriété Nom n'est pas trouvé. Si ce n'est
pas zéro, l'uid renvoyé est unique à ceNom et rappel et peut être utilisé avec unbind_uid()
pour délier.
Lors de la liaison d'un rappel avec largs et/ou kwargs, funbind() doit être utilisé pour la déliaison. Si
aucun largs et kwargs n'est fourni,délier() peut également être utilisé. unbind_uid() peut être utilisé
dans les deux cas.
This method passes on any caught positional and/or keyword arguments to the callback,
removing the need to call partial. When calling the callback the expended largs are passed on
followed by instance/value (just instance for kwargs) followed by expended kwargs.
class DemoBox(BoxLayout):
214
(continued from previous page)
Note: Since the kv lang uses this method to bind, one has to implement this method, instead of
bind() when creating a non EventDispatcher based class used with the kv lang. See
Observable for an example.
Changed in version 1.9.1: The ref keyword argument has been added.
Note: It is safe to use funbind() to unbind a function bound with bind() as long as no
keyword and positional arguments are provided to funbind().
get_property_observers(name, args=False)
Returns a list of methods that are bound to the property/event passed as the name argument:
widget_instance.get_property_observers('on_release')
Parameters
If True, each element in the list is a 5-tuple of (callback, largs, kwargs, is_ref, uid),
where is_ref indicates whether callback is a weakref, and uid is the uid given by
fbind(), or None if bind() was used. Defaults to False.
Returns The list of bound callbacks. See args for details.
215
Changed in version 1.9.0: args has been added.
getter(name)
Return the getter of a property.
is_event_type(event_type)
Return True if the event_type is already registered.
properties() → dict
Return all the properties in the class in a dictionary of key/property class. Can be used for
introspection.
property(name, quiet=False)
Get a property instance from the property name. If quiet is True, None is returned instead of
raising an exception when name is not a property. Defaults to False.
proxy_ref
Returns a WeakProxy reference to the EventDispatcher.
New in version 1.9.0.
Changed in version 2.0.0: Previously it just returned itself, now it actually returns a
WeakProxy.
register_event_type(event_type)
Register an event type with the dispatcher.
Registering event types allows the dispatcher to validate event handler names as they are
attached and to search attached objects for suitable handlers. Each event type declaration must:
class MyWidget(Widget):
def __init__(self, super( * *kwargs):
MyWidget, self).__init__(**kwargs)
self.register_event_type('on_swipe')
setter(name)
Return the setter of a property. Use: instance.setter(‘name’). The setter is a convenient callback
function useful if you want to directly bind one property to another. It returns a partial
216
function that will accept (obj, value) args and results in the property ‘name’ of instance being set
to value.
class ExampleWidget(Widget):
number1 = NumericProperty(None)
number2 = NumericProperty(None)
<ExampleWidget>:
number2: self.number1
unbind(**kwargs)
Unbind properties from callback functions with similar usage as bind().
If a callback has been bound to a given event or property multiple times, only the first
occurrence will be unbound.
Note: It is safe to use unbind() on a function bound with fbind() as long as that function
was originally bound without any keyword and positional arguments. Otherwise, the
function will fail to be unbound and you should use funbind() instead.
unbind_uid(name, uid)
Uses the uid returned by fbind() to unbind the callback.
This method is much more efficient than funbind(). If uid evaluates to False (e.g. 0) a
ValueError is raised. Also, only callbacks bound with fbind() can be unbound with this
method.
Since each call to fbind() will generate a unique uid, only one callback will be removed. If uid is
not found among the callbacks, no error is raised.
E.g.:
if not uid:
raise Exception('Binding failed').
...
btn6.unbind_uid('on_press', uid)
unregister_event_type(event_type)
Unregister an event type in the dispatcher.
217
class kivy.event.ObjectWithUid
Bases: builtins.object
(internal) This class assists in providing unique identifiers for class instances. It is not intended for
direct usage.
class kivy.event.Observable
Bases: kivy.event.ObjectWithUid
Observable is a stub class defining the methods required for binding. EventDispatcher is (the)
one example of a class that implements the binding interface. See EventDispatcher for details.
bind(**kwargs)
fbind(name, func, *largs, **kwargs)
See EventDispatcher.fbind().
Note: To keep backward compatibility with derived classes which may have inherited from
Observable before, the fbind() method was added. The default implementation of fbind()
is to create a partial function that it passes to bind while saving the uid and largs/kwargs.
However, funbind() (and unbind_uid()) are fairly inefficient since we have to first lookup
this partial function using the largs/kwargs or uid and then call unbind() on the returned
function. It is recommended to overwrite these methods in derived classes to bind directly
for better performance.
Similarly to EventDispatcher.fbind(), this method returns 0 on failure and a positive
unique uid on success. This uid can be used with unbind_uid().
The factory can be used to automatically register any class or module and instantiate classes from it
anywhere in your project. It is an implementation of the Factory Pattern.
The class list and available modules are automatically generated by setup.py.
218
> > > from kivy.factory import Factory
> > > Factory.register('MyWidget', cls=MyWidget)
By default, the first classname you register via the factory is permanent. If you wish to change the
registered class, you need to unregister the classname before you re-assign it:
exception kivy.factory.FactoryException
Bases: Exception
kivy.geometry.circumcircle(a, b, c)
Computes the circumcircle of a triangle defined by a, b, c. See: http://en.wikipedia.org/wiki/
Circumscribed_circle
Parameters
a: iterable containing at least 2 values (for x and y) The 1st point of the triangle.
b: iterable containing at least 2 values (for x and y) The 2nd point of the triangle.
c: iterable containing at least 2 values (for x and y) The 3rd point of the triangle.
Return
For a description of the problem being solved, see the Smallest Circle Problem.
The function uses Applet’s Algorithm, the runtime is O(h^3, *n), where h is the number of points
in the convex hull of the set of points. But it runs in linear time in almost all real world cases.
See: http://tinyurl.com/6e4n5yb
Parameters
219
20.14 Gesture recognition
This class allows you to easily create new gestures and compare them:
# Create a gesture g =
Gesture()
g.add_stroke(point_list=[(1,1), g.normalize (3,4), (2,1)])
()
#...
gdb.find(g2)
Warning: You don’t really want to do this: it’s more of an example of how to construct gestures
dynamically. Typically, you would need a lot more points, so it’s better to record gestures in a file and
reload them to compare later. Look in the examples/gestures directory for an example of how to do
that.
class kivy.gesture.Gesture(tolerance=None)
Bases: builtins.object
A python implementation of a gesture recognition algorithm by Oleg Dopertchouk: http://www.
gamedev.net/reference/articles/article2039.asp
add_stroke(point_list=None)
Adds a stroke to the gesture and returns the Stroke instance. Optional point_list argument is a
list of the mouse points for the stroke.
dot_product(comparison_gesture)
Calculates the dot product of the gesture with another gesture.
get_rigid_rotation(dstpts)
Extract the rotation to apply to a group of points to minimize the distance to a second group of
points. The two groups of points are assumed to be centered. This is a simple version that just
picks an angle based on the first point of the gesture.
get_score(comparison_gesture, rotation_invariant=True)
Returns the matching score of the gesture against another gesture.
normalize(stroke_samples=32)
Runs the gesture normalization algorithm and calculates the dot product with self.
class kivy.gesture.GestureDatabase
Bases: builtins.object
Class to handle a gesture database.
add_gesture(gesture)
Add a new gesture to the database.
220
find(gesture, minscore=0.9, rotation_invariant=True)
Find a matching gesture in the database.
gesture_to_str(gesture)
Convert a gesture into a unique string.
str_to_gesture(data)
Convert a unique string to a gesture.
class kivy.gesture.GestureStroke
Bases: builtins.object
Gestures can be made up of multiple strokes.
add_point(x=x_pos, y=y_pos)
Adds a point to the stroke.
center_stroke(offset_x, offset_y)
Centers the stroke by offsetting the points.
normalize_stroke(sample_points=32)
Normalizes strokes so that every stroke has a standard number of points. Returns True if stroke
is normalized, False if it can’t be normalized. sample_points controls the resolution of the stroke.
points_distance(point1=GesturePoint, point2=GesturePoint)
Returns the distance between two GesturePoints.
scale_stroke(scale_factor=float)
Scales the stroke down by scale_factor.
stroke_length(point_list=None)
Finds the length of the stroke. If a point list is given, finds the length of that list.
Deprecated since version 1.10.0: The interactive launcher has been deprecated.
The InteractiveLauncher provides a user-friendly python shell interface to an App so that it can be
prototyped and debugged interactively.
Note: The Kivy API intends for some functions to only be run once or before the main EventLoop has
started. Methods that can normally be called during the course of an application will work as intended, but
specifically overriding methods such as on_touch() dynamically leads to trouble.
Take your existing subclass of App (this can be production code) and pass an instance to the
InteractiveLauncher constructor.
class MyApp(App):
(continues on next page)
221
(continued from previous page)
def build(self):
return Button(text='Hello Shell')
After pressing enter, the script will return. This allows the interpreter to continue running. Inspection or
modification of the App can be done safely through the InteractiveLauncher instance or the provided
SafeMembrane class instances.
Note: If you want to test this example, start Python without any file to have already an interpreter, and
copy/paste all the lines. You’ll still have the interpreter at the end + the kivy application running.
IPython provides a fast way to learn the Kivy API. The App instance and all of its attributes, including
methods and the entire widget tree, can be quickly listed by using the ‘.’ operator and pressing ‘tab’. Try
this code in an Ipython shell.
class MyPaintWidget(Widget):
def on_touch_down(self, with touch):
self.canvas:
Color(1, 1, 0) d =
30.
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
class TestApp(App):
def build(self):
return Widget()
i = InteractiveLauncher(TestApp()) i.run()
i.safeIn()
# The application is now blocked.
# Click on the screen several times. i.safeOut()
222
(continued from previous page)
Note: All of the proxies used in the module store their referent in the _ref attribute, which can be
accessed directly if needed, such as for getting doc strings. help() and type() will access the proxy, not
its referent.
Both the InteractiveLauncher and SafeMembrane hold internal references to the EventLoop’s ‘safe’
and ‘confirmed’ threading.Event objects. You can use their safing methods to control the application
manually.
SafeMembrane.safeIn() will cause the application to pause and SafeMembrane.safeOut() will allow
a paused application to continue running. This is potentially useful for scripting actions into functions
that need the screen to update etc.
Note: The pausing is implemented via the Clocks' schedule_once() method and occurs before the
start of each frame.
Note: This module uses threading and object proxies to encapsulate the running App. Deadlocks and
memory corruption can occur if making direct references inside the thread without going through the
provided proxy(s).
The InteractiveLauncher can have attributes added to it exactly like a normal object and if these were
created from outside the membrane, they will not be threadsafe because the external references to them
in the python interpreter do not go through InteractiveLauncher’s membrane behavior, inherited from
SafeMembrane.
To threadsafe these external references, simply assign them to SafeMembrane instances of themselves like so:
interactiveLauncher.attribute = myNewObject
# myNewObject is unsafe
myNewObject = SafeMembrane(myNewObject)
# myNewObject is now safe. Call at will.
myNewObject.method()
223
TODO
Unit tests, examples, and a better explanation of which methods are safe in a running application would be
nice. All three would be excellent.
with safe:
foo()
safeIn()
Provides a thread-safe entry point for interactive launching.
safeOut()
Provides a thread-safe exit point for interactive launching.
This module contains the Kivy core functionality and is not intended for end users. Feel free to look
through it, but bare in mind that calling any of these methods directly may result in an unpredictable
behavior as the calls access directly the event loop of an application.
class kivy.base.EventLoopBase
Bases: kivy.event.EventDispatcher
Main event loop. This loop handles the updating of input and dispatching events.
add_event_listener(listener)
Add a new event listener for getting touch events.
add_input_provider(provider, auto_remove=False)
Add a new input provider to listen for touch events.
add_postproc_module(mod)
Add a postproc input module (DoubleTap, TripleTap, DeJitter RetainTouch are defaults).
async async_idle()
Identical to idle(), but instead used when running within an async event loop.
close()
Exit from the main loop and stop all configured input providers.
224
dispatch_input()
Called by EventLoopBase.idle() to read events from input providers, pass events to
postproc, and dispatch final events.
ensure_window()
Ensure that we have a window.
exit()
Close the main loop and close the window.
idle()
This function is called after every frame. By default:
on_pause()
Event handler for on_pause which will be fired when the event loop is paused.
on_start()
Event handler for on_start which will be fired right after all input providers have been started.
on_stop()
Event handler for on_stop events which will be fired right after all input providers have been
stopped.
post_dispatch_input(etype, me)
This function is called by EventLoopBase.dispatch_input() when we want to dispatch an
input event. The event is dispatched to all listeners and if grabbed, it’s dispatched to
grabbed widgets.
remove_android_splash(*args)
Remove android presplash in SDL2 bootstrap.
remove_event_listener(listener)
Remove an event listener from the list.
remove_input_provider(provider)
Remove an input provider.
Changed in version 2.1.0: Provider will be also removed if it exist in auto-remove list.
remove_postproc_module(mod)
Remove a postproc module.
run()
Main loop
set_window(window)
Set the window used for the event loop.
start()
Must be called before EventLoopBase.run(). This starts all configured input providers.
Changed in version 2.1.0: Method can be called multiple times, but event loop will start only
once.
stop()
Stop all input providers and call callbacks registered using EventLoop.add_stop_callback().
Changed in version 2.1.0: Method can be called multiple times, but event loop will stop only
once.
225
property touches
Return the list of all touches currently in down or move states.
class kivy.base.ExceptionHandler
Bases: builtins.object
Base handler that catches exceptions in runTouchApp(). You can subclass and extend it as follows:
class E(ExceptionHandler):
def handle_exception(self, inst):
Logger.exception('Exception caught by ExceptionHandler') return
ExceptionManager.PASS
ExceptionManager.add_handler(E())
Then, all exceptions will be set to PASS, and logged to the console!
handle_exception(exception)
Called by ExceptionManagerBase to handle a exception.
Defaults to returning ExceptionManager.RAISE that re-raises the exception. Return
ExceptionManager.PASS to indicate that the exception was handled and should be ignored.
This may be called multiple times with the same exception, if ExceptionManager.RAISE is
returned as the exception bubbles through multiple kivy exception handling levels.
kivy.base.ExceptionManager: kivy.base.ExceptionManagerBase =
<kivy.base.ExceptionManagerBase object>
The ExceptionManagerBase instance that handles kivy exceptions.
class kivy.base.ExceptionManagerBase
Bases: builtins.object
ExceptionManager manages exceptions handlers.
PASS = 1
The exception should be ignored as it was handled by the handler.
RAISE = 0
The exception should be re-raised.
add_handler(cls)
Add a new exception handler to the stack.
handle_exception(inst)
Called when an exception occurred in the runTouchApp() main loop.
remove_handler(cls)
Remove the exception handler from the stack.
kivy.base.runTouchApp(widget=None, embedded=False)
Static main function that starts the application loop. You can access some magic via the following
arguments:
226
Parameters
<empty> To make dispatching work, you need at least one input listener. If not,
application will leave. (MTWindow act as an input listener)
widget If you pass only a widget, a MTWindow will be created and your widget
will be added to the window as the root widget.
The Kivy Logger class provides a singleton logger instance. This instance exposes a standard Python logger
object but adds some convenient features.
All the standard logging levels are available : trace, debug, info, warning, error and critical.
try:
raise Exception('bleh') except
Exception:
Logger.exception('Something happened!')
The message passed to the logger is split into two parts separated by a colon (:). The first part is used as a
title and the second part is used as the message. This way, you can “categorize” your messages easily.
# will appear as
You can change the logging level at any time using the setLevel method.
Logger.setLevel(LOG_LEVELS["debug"])
227
20.17.2 Features
Although you are free to use standard python loggers, the Kivy Logger offers some solid benefits and
useful features. These include:
• color-coded output
• output to stdout by default
Kivys’ logger was designed to be used with kivy apps and makes logging from Kivy apps more convenient.
[kivy]
log_level = info
log_enable = 1
log_dir = logs
log_name = kivy_%y-%m-%d_%_.txt
log_maxfiles = 100
More information about the allowed values are described in the kivy.config module.
Even if the logger is not enabled, you still have access to the last 100 messages:
print(LoggerHistory.history)
class kivy.logger.LoggerHistory(level=0)
Bases: logging.Handler
emit(message)
Do whatever it takes to actually log the specified logging record.
flush()
Ensure all logging output has been flushed.
228
20.18 Low level Metrics
kivy._metrics.dispatch_pixel_scale(*args)
Dispatches all properties that and watch pixel_scale_observers.
This should be called by Metrics when it changes any of the scaling properties.
20.19 Metrics
A screen is defined by its physical size, density and resolution. These factors are essential for creating UI’s
with correct size everywhere.
In Kivy, all the graphics pipelines work with pixels. But using pixels as a measurement unit is problematic
because sizes change according to the screen.
20.19.1 Dimensions
If you want to design your UI for different screen sizes, you will want better measurement units to work
with. Kivy provides some more scalable alternatives.
Units
pt Points - 1/72 of an inch based on the physical size of the screen. Prefer to use sp
instead of pt.
sp Scale-independent Pixels - This is like the dp unit, but it is also scaled by the user’s
font size preference. We recommend you use this unit when specifying font sizes, so
the font size will be adjusted to both the screen density and the user’s preference.
229
20.19.2 Examples
Here is an example of creating a label with a sp font_size and setting the height manually with a 10dp
margin:
# :kivy 1.5.0
<MyWidget>:
Label:
text: 'Hello world'
font_size: '15sp'
size_hint_y: None
height: self.texture_size[1] + dp(10)
The metrics cannot be changed at runtime. Once a value has been converted to pixels, you can’t retrieve
the original value anymore. This stems from the fact that the DPI and density of a device cannot be
changed at runtime.
• KIVY_METRICS_DENSITY: if set, this value will be used for density instead of the systems one. On
android, the value varies between 0.75, 1, 1.5 and 2.
• KIVY_METRICS_FONTSCALE: if set, this value will be used for fontscale instead of the systems
one. On android, the value varies between 0.8 and 1.2.
• KIVY_DPI: if set, this value will be used for dpi. Please note that setting the DPI will not impact the dp/
sp notation because these are based on the screen density.
For example, if you want to simulate a high-density screen (like the HTC One X):
You can also simulate an alternative user preference for fontscale as follows:
Changed in version 2.1.0: Metrics is now a Context registered variable (like e.g. Clock).
class kivy.metrics.MetricsBase(**kwargs)
Bases: kivy.event.EventDispatcher
Class that contains the default attributes for Metrics. Don’t use this class directly, but use the Metrics
instance.
cm: float
The scaling factor that converts from centimeters to pixels.
230
cm is a AliasProperty containing the factor. E.g in KV: width: self.
texture_size[0] + 10 * Metrics.cm will update width when cm changes from a screen
configuration change.
density: float
The density of the screen.
This value is 1 by default on desktops but varies on android depending on the screen.
density is a AliasProperty and can be set to change the value. But, the density is reloaded
and reset if we got it from the Window and the Window density changed.
dp: float
The scaling factor that converts from density-independent pixels to pixels.
dpi: float
The DPI of the screen.
Depending on the platform, the DPI can be taken from the Window provider (Desktop
mainly) or from a platform-specific module (like android/ios).
dpi is a AliasProperty and can be set to change the value. But, the density is reloaded and
reset if we got it from the Window and the Window dpi changed.
dpi_rounded: int
Return the dpi of the screen, rounded to the nearest of 120, 160, 240 or 320.
This value is 1 by default but can vary between 0.8 and 1.2.
231
reset_metrics()
Resets the dpi/density/fontscale to the platform values, overwriting any manually set
values.
sp: float
The scaling factor that converts from scale-independent pixels to pixels.
kivy.metrics.cm(value) → float
Convert from centimeters to pixels
kivy.metrics.dp(value) → float
Convert from density-independent pixels to pixels
kivy.metrics.inch(value) → float
Convert from inches to pixels
kivy.metrics.mm(value) → float
Convert from millimeters to pixels
kivy.metrics.pt(value) → float
Convert from points to pixels
kivy.metrics.sp(value) → float
Convert from scale-independent pixels to pixels
Warning: This is experimental and subject to change as long as this warning notice is present.
232
Candidate represents a user-input gesture that is used to search the gesture database for matches. It is
normally instantiated automatically by calling Recognizer.recognize().
gdb = Recognizer()
# Now you can search for the 'T' gesture using similar data (user input).
# This will trigger both of the callbacks bound above. gdb.recognize([
On the next Clock tick, the matching process starts (and, in this case, completes).
To track individual calls to Recognizer.recognize(), use the return value (also a ProgressTracker
instance)
# Same as above, but keep track of progress using returned value progress = gdb.
recognize([
[Vector(45, 8), Vector(110, 12)], [Vector(88, 9
), Vector(85, 95)]])
progress.bind(on_progress=my_other_callback) print(
progress.progress) # = 0
(continues on next page)
233
(continued from previous page)
print(result.progress) # = 1
add_stroke(stroke)
Add a stroke to the candidate; this will invalidate all previously computed vectors
get_angle_similarity(tpl, **kwargs)
(Internal use only) Compute the angle similarity between this Candidate and a
UnistrokeTemplate object. Returns a number that represents the angle similarity (lower is
more similar).
get_protractor_vector(numpoints, orientation_sens)
(Internal use only) Return vector for comparing to a UnistrokeTemplate with Protractor
get_start_unit_vector(numpoints, orientation_sens)
(Internal use only) Get the start vector for this Candidate, with the path resampled to numpoints
points. This is the first step in the matching process. It is compared to a UnistrokeTemplate
object’s start vector to determine angle similarity.
prepare(numpoints=None)
Prepare the Candidate vectors. self.strokes is combined to a single unistroke (connected endto-
end), resampled to numpoints points, and then the vectors are calculated and stored in self.db
(for use by get_distance and get_angle_similarity)
234