我可以在应用程序运行时多次加载.kv文件吗?

2024-05-03 15:55:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个不同的.kv文件:

  1. 文件定义主界面-->PriceTrackerUI.kv
  2. 文件定义弹出窗口-->PopupWindow.kv

我想“刷新”弹出窗口的内容,每次我关闭它

PopupWindow.kv中,程序通过加载已存在于目录中的文件来打开一个映像。每次运行应用程序的后期都会覆盖此文件。问题是,.kv文件完全是在程序初始化时加载的,以后不会再加载。由于它在主UI窗口中是有意义的,而在弹出窗口中则没有,弹出窗口的内容会随着主UI窗口中按钮的每次单击而改变

下面是一个最小的代码

PopupWindow.kv

<PopupWindow>
    orientation: 'vertical'
    size_hint: 1, .9
    BoxLayout:
        orientation: 'horizontal'
        cols: 2

    AsyncImage:
        source: root.daily  # loading image stored under that variable
        allow_stretch: True
        size_hint: .9, 1
        pos_hint: {'x': 0, 'center_y': .5}

   (...)

PriceTrackerUI

<SearchPerformer>
GridLayout:
    size: root.size
    cols: 2
    rows: 3

  (...)

    FloatLayout:
        Button:
            text: 'Search'
            size_hint: .5, .4
            pos_hint: {"x": .75, "top": .9}
            border: 20, 20, 20, 20
            on_press: root.input_grabber(root.dt)
            on_release: root.clear()
            on_release: root.hit_enter()

main.py

import UI


UI.PriceTrackerUIApp().run()

UI.py

import kivy
import database
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.properties import StringProperty
from kivy.lang import Builder

kivy.require('1.11.1')


user_input = []

Builder.load_file('PopupWindow.kv')


class PopupWindow(BoxLayout):
    daily = StringProperty('./daily.png')


def popup_show():
    pop = PopupWindow()

    pop_win = Popup(title="Analysis", content=pop, size_hint=(.9, .9))
    pop_win.open()


class SearchPerformer(BoxLayout):
    dt = database

    def hit_enter(self):
        popup_show()

    def input_grabber(self, database):
        specs = [self.ids.crmk.text, self.ids.crmd.text, self.ids.cryr.text, self.ids.crft.text]
        (...)
        user_input.extend(specs)
        database.add_to_database()
        database.query_database()
        database.run_plot() # daily.png image gets updated after running that method


class PriceTrackerUIApp(App):
    def build(self):
        return SearchPerformer()

Tags: 文件textfromimportselfuisizeroot
2条回答

您可以使用Builder.load_fileBuilder.load_string在任意点加载kv文件。当您实例化一个小部件时,将应用任何以前加载的规则

如果在更改daily.png文件后试图打开新的Popup,则当前代码应在新的Popup文件中反映更改的daily.png。重新加载kv不会影响这一点

如果试图更新已打开的Popup中的AsyncImage,则重新加载kv将无效。在这种情况下,您只需要调用AsnycImagereload()方法。当然,这意味着您必须保留对PopupWindow的引用,并可能向AsyncImage添加一个id。因此,要添加一个id,稍微修改一下kv

<PopupWindow>
    orientation: 'vertical'
    size_hint: 1, .9
    BoxLayout:
        orientation: 'horizontal'
        cols: 2

    AsyncImage:
        id: img   # id to be used for calling reload()
        source: root.daily  # loading image stored under that variable
        allow_stretch: True
        size_hint: .9, 1
        pos_hint: {'x': 0, 'center_y': .5}

并在代码中使用它(以及一些小的修改):

def popup_show():
    pop = PopupWindow()

    pop_win = Popup(title="Analysis", content=pop, size_hint=(.9, .9))
    pop_win.open()
    return pop   # save a reference to the `PopupWindow`


class SearchPerformer(BoxLayout):
    dt = database
    pop = ObjectProperty(None)

    def hit_enter(self):
        self.pop = popup_show()  # retain reference to `PopupWindow`

    def input_grabber(self, database):
        specs = [self.ids.crmk.text, self.ids.crmd.text, self.ids.cryr.text, self.ids.crft.text]
        (...)
        user_input.extend(specs)
        database.add_to_database()
        database.query_database()
        database.run_plot() # daily.png image gets updated after running that method
        if self.pop is not None:
            self.pop.ids.img.reload()   # reload the updated daily.png

相关问题 更多 >