【问题标题】:multiple widgets in KivyKivy 中的多个小部件
【发布时间】:2020-01-31 07:30:50
【问题描述】:

我是 python 前端的新手。目前我坚持集成 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()  

我需要在一个窗口中同时显示,并且时钟应该在右上角。

【问题讨论】:

    标签: python widget kivy kivy-language


    【解决方案1】:

    这是一种方法:

    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__': 完成的。所以,我稍微修改了这些文件:

    时间标签.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()
    

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

    如果要更新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_sourceStringProperty 将包含CenteredAsyncImage 的来源。对self.bind 的调用安排对img_source 的任何更改以触发对set_casi_source() 的调用,从而为CenteredAsyncImage 设置source。请注意,在build() 方法中设置img_source 将失败,因为它使用ids 并且它们尚未在build() 方法中设置。因此,在 App 构建后的任何时候,只需更改 img_source 属性就会更改 CenteredAsyncImage

    【讨论】:

    • 嗨@John,感谢您的重播。此代码正在运行。但我不能在代码中硬编码图像名称。我想用我的主要 python 文件更新图像。那么我需要做些什么修改呢?
    猜你喜欢
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-14
    相关资源
    最近更新 更多