如何为每个屏幕添加自己的.py和.kv文件?

时间:2015-08-19 18:01:28

标签: python kivy

我希望每个sreen都有一个单独的.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

1 个答案:

答案 0 :(得分:2)

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

每个屏幕都是继承自Screen的类,在单独的.py文件中定义这些屏幕类然后将它们导入到main.py文件中并不困难。我之前做过这个。例如,我有我的main.py(你需要的),我把所有各种屏幕定义在一个名为&#39; game_screen.py&#39;的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文件的方法,你可以实现你所要求的......然后决定这是否是一个很好的方法。< / p>