Je suis nouveau sur le front-end python. Actuellement, je suis coincé avec l'intégration de 2 programmes Python Kivy. Chacun d'eux a un widget différent. L'un est le chargement d'image asynchrone et l'autre est le widget d'horloge. Quelqu'un peut-il m'aider à intégrer ces multiples widgets dans un seul fichier python. J'ajoute mes codes python ci-dessous. Aidez-moi, s'il vous plaît.

Chargement d'image asynchrone

from kivy.app import App

from kivy.uix.image import AsyncImage
from kivy.lang import Builder

Builder.load_string('''
<CenteredAsyncImage>:
    allow_stretch: True
    keep_ratio: True
    size_hint_y: None
    pos_hint: {'center_x': 0.5, 'center_y': 0.5}
    height: dp(800)
    mipmap: True
''')

class CenteredAsyncImage(AsyncImage):
    pass

class TestAsyncApp(App):
    def build(self):
        img = 'edited_background.jpg' 
        return CenteredAsyncImage(source=img)

if __name__ == '__main__':
    TestAsyncApp().run()

Widget d'horloge

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.base import Builder
from kivy.uix.image import Image
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
from kivy.core.window import Window
import time


class Time(Label):
    def updateTime(self,*args):
        self.text = time.asctime()
class TimeApp(App):
    def build(self):
        t=Time()
        Clock.schedule_interval(t.updateTime,1)
        return(t)

TimeApp().run()  

Je dois afficher les deux dans une seule fenêtre et l'horloge doit être dans le coin supérieur droit.

0
Ajith Balakrishnan 31 janv. 2020 à 10:30

1 réponse

Meilleure réponse

Voici une façon de procéder:

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder

from centeredasyncimage import CenteredAsyncImage
from timelabel import Time

theroot = Builder.load_string('''
RelativeLayout:
    CenteredAsyncImage:
        source: 'img.jpg'
        size_hint: 0.25, 0.25
        pos_hint: {'x': 0, 'top': 1.0}
    Time:
        id: time
        size_hint: 0.25, 0.25
        pos_hint: {'right': 1.0, 'top': 1.0}
''')


class TheApp(App):
    def build(self):

        # schedule the start of the clock
        Clock.schedule_once(self.start_time_updates)
        return theroot

    def start_time_updates(self, dt):
        t = self.root.ids.time
        # schedule the clock update every second
        Clock.schedule_interval(t.updateTime,1)


if __name__ == '__main__':
    TheApp().run()

Cela suppose que le CenteredAsyncImge est défini dans un fichier nommé centeredasyncimage.py et que Time est défini dans un fichier nommé timelabel.py.

Dans ces fichiers, le code utilisé pour exécuter un App doit être protégé contre l'exécution lorsque le fichier est importé. Cela se fait en utilisant if __name__ == '__main__':. J'ai donc légèrement modifié ces fichiers :

Timelabel.py :

from kivy.uix.label import Label
import time


class Time(Label):
    def updateTime(self,*args):
        self.text = time.asctime()


if __name__ == '__main__':
    from kivy.app import App
    from kivy.clock import Clock
    class TimeApp(App):
        def build(self):
            t=Time()
            Clock.schedule_interval(t.updateTime,1)
            return(t)

    TimeApp().run()

Et centeredasyncimage.py :

from kivy.uix.image import AsyncImage
from kivy.lang import Builder

Builder.load_string('''
<CenteredAsyncImage>:
    allow_stretch: True
    keep_ratio: True
    size_hint_y: None
    pos_hint: {'center_x': 0.5, 'center_y': 0.5}
    height: dp(800)
    mipmap: True
''')


class CenteredAsyncImage(AsyncImage):
    pass


if __name__ == '__main__':
    from kivy.app import App
    class TestAsyncApp(App):
        def build(self):
            img = 'edited_background.jpg'
            return CenteredAsyncImage(source=img)

    TestAsyncApp().run()

Si vous souhaitez mettre à jour la source de l'image pour le CenteredAsyncImage, vous pouvez simplement modifier le fichier contenant le App comme :

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import StringProperty

from centeredasyncimage import CenteredAsyncImage
from timelabel import Time

theroot = Builder.load_string('''
RelativeLayout:
    CenteredAsyncImage:
        id: casi
        source: 'img.jpg'   # default image (this is optional)
        size_hint: 0.25, 0.25
        pos_hint: {'x': 0, 'top': 1.0}
    Time:
        id: time
        size_hint: 0.25, 0.25
        pos_hint: {'right': 1.0, 'top': 1.0}
''')


class TheApp(App):
    img_source = StringProperty()  # property to hold image source
    def build(self):
        self.bind(img_source=self.set_casi_source)   # bind source property
        Clock.schedule_once(self.start_time_updates)
        return theroot

    def set_casi_source(self, app, val, *args):
        # this sets the image source
        self.root.ids.casi.source = val

    def start_time_updates(self, dt):
        t = self.root.ids.time
        Clock.schedule_interval(t.updateTime,1)


if __name__ == '__main__':
    TheApp().run()

Le img_source StringProperty contiendra la source du CenteredAsyncImage. L'appel à self.bind organise toute modification du img_source pour déclencher un appel à set_casi_source(), qui définit le source pour le CenteredAsyncImage. Notez que la définition de img_source dans la méthode build() échouera, car elle utilise ids et ils ne sont pas encore configurés dans la méthode build(). Ainsi, à tout moment après la construction de App, le simple fait de changer la propriété img_source changera le CenteredAsyncImage.

0
John Anderson 3 févr. 2020 à 17:13