Outils pour utilisateurs

Outils du site


kivy_comment_faire_un_tas_de_chose

Kivy: Comment faire ou ne pas faire un tas de chose

Comment chercher ?

Sur internet

  • Dans la doc officielle, mais les chances de trouver sont quasi nulles.
  • Dans un moteur de recherche: ça finit souvent par des posts sur stackoverflow, avec des réponses médiocres fausses, uniquement motivées par le gain de points !

Une bonne solution: Les exemples des sources de kivy

  • Télécharger les sources sur github
  • Dans votre EDI créer un projet avec uniquement les exemples
  • Rechercher dans les fichiers: si vous chercher “source:”, vous aurez la liste de tous les fichiers qui utilisent “source:”. Si c'est un kv, trouver le .py corespondant pour l'exécuter.

Gallery of Examples Il faut fouiller!

Des explications avec les exemples des sources

Une liste de scripts qui explique bien:

Adapter la résolution dpi sur son PC

  • Sur votre PC, définir la taille de votre fenêtre
from plyer import utils
 
from oscpy.client import OSCClient
from oscpy.server import OSCThreadServer
 
print("Platform =", utils.platform)
ANDROID = utils.platform._platform_android  # retourne True ou False
print("Android =", ANDROID)
if not ANDROID:
    from kivy.core.window import Window
    # Simulation de l'écran de mon tél: 1280*720
    k = 0.8
    WS = (int(720*k), int(1280*k))
    Window.size = WS
    os.environ['JAVA_HOME'] = '/usr/lib/jvm/adoptopenjdk-8-hotspot-amd64'
 
from jnius import autoclass

Lancer le main.py avec:

KIVY_METRICS_FONTSCALE=1.2 python3 main.py

avec une valeur “1.2” à adapter pour que vous ayez le même graphisme sur votre PC que sur votre téléphone.

Comment lister tous les widgets dans le python

Par exemple, extrait de smartcitizen main.py#L83:

# Recherche de tous les widgets de self
print([type(widget) for widget in self.walk(loopback=True)])
# Recherche de tous les widgets de Screen1
print(self.ids.sm)
f = self.ids.sm.get_screen("first")
print([type(widget) for widget in f.walk(loopback=True)])

Sortie de [type(widget) for widget in self.walk(loopback=True)] dans SmartCitizen()

<class '__main__.SmartCitizen'>,
<class 'kivy.uix.actionbar.ActionBar'>,
<class 'kivy.uix.actionbar.ActionView'>,
<class 'kivy.uix.actionbar.ActionButton'>,
<class 'kivy.uix.image.Image'>,
<class 'kivy.uix.screenmanager.ScreenManager'>,
<class '__main__.MainScreen'>,
<class 'kivy.uix.boxlayout.BoxLayout'>,
<class 'kivy.uix.label.Label'>,
<class 'kivy.uix.boxlayout.BoxLayout'>,
......

Comment passer un attribut d'une class à une autre

En fait, comment passer d'un objet à un autre !

Faire des print(de quoi ?). Commencer par

print(dir(self))

puis dans la liste des méthodes et attributs, ayez de nez. Si app est dans la liste:

print(dir(self.app))

Comment récupérer self.app dans tous les objets

Une solution élégante est utilisée dans accelerometer: main.py avec ces extraits modifiés pour expliquer:

class AccelerometerApp(App):
    def build(self):
        return Accelerometer(self)
 
class Accelerometer(BoxLayout):
    def __init__(self, app, **kwargs):
        super().__init__(**kwargs)
        self.app = app
        self.app.osc = OSC()
 
class OSC:
    def __init__(self):
        self.histo = []
        self.server = OSCThreadServer()
        self.server.bind(b'/histo', self.on_histo)
 
    def on_histo(self, *args):
        self.histo = ....
 
class Screen2:
    def __init__(self):
        self.app = App.get_running_app()
        # et appel de l'attribut histo de OSC avec
        self.app.osc.histo
        Clock.schedule_once(self._once, 1)
 
    def _once(self, dt):
        Clock.schedule_interval(self.update, 0.1)
 
    def update(self, dt): 
        blabla = self.app.osc.histo 
        # blabla retrouve la valeur de histo de OSC !!!!

Pourquoi définir les attributs appelés dans *.kv comme attributs de classe ?

Parce que c'est comme ça ? Quand lama fâché, lui toujours faire ainsi !

Voir l'exemple ci-dessous.

Comment changer la couleur d'un Rectangle ?

Répond aussi à la Question:

Comment définir et accéder aux attributs dans le main et le *.kv ?

Les attributs des widgets défini dans le *.kv sont accessibles depuis le main, seulement si les attributs du widget sont définis en attribut de classe.

Exemple extrait de multipong:

*.kv

<PongPaddle>:
    canvas:
        Color:
            rgb: self.rect_color
        Rectangle:
            pos: self.pos
            size: root.height/65, root.height/7
 
<Screen1>:
    ...
    ...
    paddle_0: paddle0
    ...
    ...
    PongPaddle:  # paddle_0
        id: paddle0
        pos: self.pos
    ...
    ...
    BoxLayout:
        orientation: 'horizontal'
        BoxLayout:
            size_hint_x: 0.70
            canvas:
                Color:
                    rgba: 1, 1, 1, 1
                Line:
                    points: [int(x*(root.top/720)) for x in root.points]
                    joint: 'miter'
                    width: 3
                    close: 1

extrait de main.py

    ...
    ...
class PongPaddle(Widget):
    rect_color = ListProperty([1, 1, 1])
    angle = NumericProperty(0)
    ...
    ...
class Screen1(Screen):
    ...
    ...
    def apply_paddle_red_color(self, my_num):
        if my_num == 0:
            self.paddle_0.rect_color = 1, 0, 0
    ...
    ...

Button background_color

Button:
    background_normal: ''
    background_color: 1, .3, .4, .85

Pour avoir des couleurs flashy, mettre des valeurs supérieures à 1: exemple
background_color: (0, 1.2, 0, 1)

Texte en gras dans un label

        Label:
            canvas.before:
                Color:
                    rgba: 1, 1, 1, 1
                Rectangle:
                    pos: self.pos
                    size: self.size
            size_hint_y: 0.10
            markup: True
            text: '[b]' + "Mon texte" + '[/b]'
            color: 1, 0, 0.5, 1

Factory

Factory peut être utilisée pour enregistrer automatiquement toute classe ou module et en instancier des classes n'importe où dans votre projet.

Réception sur Android en Multicast

Dans buildozer.spec, définir:

android.permissions = INTERNET,CHANGE_WIFI_MULTICAST_STATE,ACCESS_NETWORK_STATE,ACCESS_WIFI_STATE

Les permissions définies dans buildozer.spec crée le bouton enable/disable dans Android / Paramètres / Application pour certaine permission: par défaut, il est disable. Quand ça ne marche pas, c'est la première chose à regarder.

Twisted dans kivy

Comment éviter ou résoudre des bugs à la compilation avec buildozer

Comment commenter dans buildozer.spec ?

Ne pas faire:

requirements = python3,kivy,plyer,numpy,oscpy#,jnius
ni
requirements = python3,kivy,plyer,numpy,oscpy #,jnius

mais

requirements = python3,kivy,plyer,numpy,oscpy
#,jnius

Le buildozer.spec est seulement presque du python. Ce commentaire maltapropo m'a donné des messages d'erreurs avec buildozer parlant de No module named 'encodings'

Bugs

Novembre 2020

Voir xclip and xsel

[CRITICAL] [Cutbuffer   ] Unable to find any valuable Cutbuffer provider. xclip - FileNotFoundError: [Errno 2] Aucun fichier ou dossier de ce type: 'xclip'

résolu avec

sudo apt install xclip

Comment avoir une action maintenue si maintien d'un Button

accelerometer.kv
            Button:
                id: recul
                markup: True
                background_color: (0, 1.2, 0, 1)
                font_size: "18sp"
                text: '[b]<<<[/b]'
                on_press: root.do_back_forward(-1)
                on_release: root.do_end()
            Button:
                id: avance
                markup: True
                background_color: (0, 1.2, 0, 1)
                font_size: "18sp"
                text: '[b]>>>[/b]'
                on_press: root.do_back_forward(1)
                on_release: root.do_end()
main.py
    def do_back_forward(self, sens):
        self.bf = 1
        bt = Thread(target=self.back_forward_loop, args=(sens, ), daemon=True)
        bt.start()
 
    def back_forward_loop(self, sens):
        while self.bf:
            sleep(0.1)
            self.gap = self.gap + sens*10
            if self.gap > 0: self.gap = 0
            l = len(self.app.osc.histo_xyz)
            if self.gap < -l + 500: self.gap = -l + 500
            print("Gap:", self.gap)
 
    def do_end(self):
        self.bf = 0
kivy_comment_faire_un_tas_de_chose.txt · Dernière modification: 2020/11/14 10:50 de serge