【问题标题】:How to add for each screen an own .py and .kv file?如何为每个屏幕添加一个自己的 .py 和 .kv 文件?
【发布时间】:2015-08-19 18:01:27
【问题描述】:

我希望每个屏幕都有一个单独的 .py 和 .kv 文件。在 main.py/main.kv 的 ScreenManager 上,应该选择屏幕。设计应从文件 screen_X.kv 加载,类等应从文件 screen_X.py 加载。

屏幕:

  • 屏幕 1
  • 屏幕 2
  • 屏幕 3

文件:

  • (main.py)
  • (showcase.kv)
  • screen_1.py
  • screen_1.kv
  • screen_2.py
  • screen_2.kv
  • screen_3.py
  • screen_3.kv

这使得程序可以很容易地扩展。我怎样才能做到这一点?


使用此代码,我已经分离了 .kv 文件。但我还需要单独的 .py 文件。

main.py

from time import time
from kivy.app import App
from os.path import dirname, join
from kivy.lang import Builder
from kivy.properties import NumericProperty, BooleanProperty, ListProperty
from kivy.clock import Clock
from kivy.uix.screenmanager import Screen


class ShowcaseScreen(Screen):
    fullscreen = BooleanProperty(False)

    def add_widget(self, *args):
        if 'content' in self.ids:
            return self.ids.content.add_widget(*args)
        return super(ShowcaseScreen, self).add_widget(*args)


class ShowcaseApp(App):
    time = NumericProperty(0)
    screen_names = ListProperty([])
    bool_menu = BooleanProperty(False)

    def build(self):
        self.title = 'hello world'
        Clock.schedule_interval(self._update_clock, 1 / 60.)
        self.available_screens = [
            'Buttons', 'CheckBoxes', 'ProgressBar', 'Switches', 'ToggleButton',
        ]
        self.screen_names = self.available_screens
        curdir = dirname(__file__)
        self.available_screens = [join(curdir, 'data', 'screens', '{}.kv'.format(fn)) for fn in self.available_screens]

        self.menu_screen = join(curdir, 'data', 'screens', '{}.kv'.format('Menu'))

        self.go_menu()

    def go_screen(self, idx):
        screen = Builder.load_file(self.available_screens[idx])
        self.root.ids.sm.switch_to(screen, direction='left')

    def go_menu(self):
        if not self.bool_menu:
            screen = Builder.load_file(self.menu_screen)
            self.root.ids.sm.switch_to(screen, direction='right')

    def _update_clock(self, dt):
        self.time = time()

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

showcase.kv

#:kivy 1.8.0
#:import KivyLexer kivy.extras.highlight.KivyLexer
#:import Factory kivy.factory.Factory

<ActionSpinnerOptions@SpinnerOption>
    background_color: .4, .4, .4, 1

<ActionSpinner@Spinner+ActionItem>
    canvas.before:
        Color:
            rgba: 0.128, 0.128, 0.128, 1
        Rectangle:
            size: self.size
            pos: self.pos
    border: 27, 20, 12, 12
    background_normal: 'atlas://data/images/defaulttheme/action_group'
    option_cls: Factory.ActionSpinnerOptions

<ActionDropdown>:
    on_size: self.width = '220dp'

<ShowcaseScreen>:
    ScrollView:
        do_scroll_x: False
        do_scroll_y: False if root.fullscreen else (content.height > root.height - dp(16))
        AnchorLayout:
            size_hint_y: None
            height: root.height if root.fullscreen else max(root.height, content.height)
            GridLayout:
                id: content
                cols: 1
                spacing: '8dp'
                padding: '8dp'
                size_hint: (1, 1) if root.fullscreen else (.8, None)
                height: self.height if root.fullscreen else self.minimum_height


BoxLayout:
    orientation: 'vertical'

    canvas.before:
        Color:
            rgb: .6, .6, .6
        Rectangle:
            size: self.size
            source: 'data/background.png'

    ActionBar:

        ActionView:
            id: av
            ActionPrevious:
                with_previous: (False if app.bool_menu == True else True) if not app.bool_menu else False
                title: 'Menu'
                on_release: app.go_menu()

            ActionSpinner:
                id: spnr
                important: True
                text: 'Select Program'
                values: app.screen_names
                on_text:
                    if (spnr.text != 'Select Program') and (sm.current != args[1]):\
                    idx = app.screen_names.index(args[1]);\
                    app.go_screen(idx)

    ScreenManager:
        id: sm
        on_current_screen:
            screen_name = args[1].name

            spnr.text = 'Select Program' if screen_name == 'Menu' else screen_name

            if screen_name == 'Menu': app.bool_menu = True
            else: app.bool_menu = False

【问题讨论】:

  • 程序中的每个屏幕都有两个源文件,这将使其更难扩展和管理,而不是更少。另外,您能否向我们展示您开始使用的一些代码,以及您为完成此所做的任何尝试?
  • 我已经编辑了我的帖子。
  • 你能把类放在单独的文件里,然后把 import 放在 main 里吗?
  • 是的,但我没有单独的课程。如何为每个屏幕获取单独的类?

标签: python kivy


【解决方案1】:

首先,您还没有提到您是否知道如何按通常的方式设置不同的屏幕,我不确定我是否在上面的代码中看到了它。如果你不这样做,有一个相当简单的教程here 创建一个简单的多屏幕设置。

每个屏幕都是一个继承自 Screen 的类,只需在单独的 .py 文件中定义这些屏幕类,然后将它们导入到您的 main.py 文件中,这并不是一件难事。我以前做过。例如,我有我的 main.py(你需要它),我在一个名为“game_screen.py”的 py 文件中定义了所有不同的屏幕,然后简单地从那里导入。

我自己并没有看到过多使用多个 kv 文件,但我知道您可以使用与下面类似的代码将 kv 规则添加到您的主(默认)kv 文件规则中。尽管我相信这些规则必须在它们生效的小部件之前加载才能正常工作。

from kivy.lang import Builder
Builder.load_file('screen1.kv')
Builder.load_file('screen2.kv')
Builder.load_file('screen3.kv')

因此,通过将您的屏幕类导入您的 main.py 并使用上述添加 kv 文件的方法,您可能会实现您的要求......然后决定这是否是一个好方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 2021-09-20
    • 1970-01-01
    • 2020-07-12
    • 2020-11-09
    • 1970-01-01
    • 2019-06-18
    相关资源
    最近更新 更多