несколько виджетов в Киви - PullRequest
0 голосов
/ 31 января 2020

Я новичок в python front-end. В настоящее время я застрял с интеграцией 2 python kivy программ. У каждого из них свой виджет. Один из них - асинхронная загрузка изображений, а второй - виджет часов. Может кто-нибудь помочь мне интегрировать эти несколько виджетов в файл python. Я добавляю свои python коды ниже. пожалуйста, помогите мне.

Асинхронная загрузка изображения

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()

Виджет часов

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()  

Мне нужно отобразить оба в одном окне и часы должны быть в правом верхнем углу.

1 Ответ

0 голосов
/ 01 февраля 2020

Вот способ сделать это:

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()

Предполагается, что CenteredAsyncImge определен в файле с именем centeredasyncimage.py, а Time определен в файле с именем timelabel.py.

В этих файлах код, используемый для запуска App, должен быть защищен от запуска при импорте файла. Это делается с помощью if __name__ == '__main__':. Итак, я немного изменил эти файлы:

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()

и centteredasyncimage.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()

Если вы хотите обновить источник изображения для CenteredAsyncImage вы можете просто изменить файл, содержащий App, следующим образом:

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()

img_source StringProperty будет содержать источник для CenteredAsyncImage. Вызов на self.bind организует любое изменение img_source, чтобы инициировать вызов на set_casi_source(), который устанавливает source для CenteredAsyncImage. Обратите внимание, что установка img_source внутри метода build() не удастся, так как он использует ids, и они еще не настроены в методе build(). Таким образом, в любое время после построения App простое изменение свойства img_source изменит CenteredAsyncImage.

...