一起使用微调器和按钮来更改屏幕

Using a spinner and button together to change screens

我找到了 this 向我展示了如何使用微调器更改屏幕的代码。它允许我切换屏幕,但我发现我还需要通过使用单个屏幕上的按钮来切换屏幕。

这是我的意思的一个例子:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.spinner import Spinner

KV = """
<MainScreen>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text: 'Edit'
            on_press: root.goEdit()
        Label:
            text: 'Main Screen'

<HelpScreen>:
    Label:
        text: 'Help Screen'

<SettingsScreen>:
    Label:
        text: 'Settings Screen'

<EditScreen>:
    name: 'edit_Screen'
    text: 'Edit Screen'

<ScreenMenu>:
    text: 'main'
    values: ('main', 'help', 'settings')
    size_hint: None, None
    size: 200, 44
"""


class MainScreen(FloatLayout):

    def goEdit(self):
        MyApp.build.screen_layout.remove_widget(MyApp.screen)
        screen = EditScreen()
        MyApp.screen = screen
        MyApp.screen_layout.add_widget(MyApp.screen)


class HelpScreen(FloatLayout):
    pass

class SettingsScreen(FloatLayout):
    pass

class EditScreen(FloatLayout):
    pass

class ScreenMenu(Spinner):
    pass


class MyApp(App):

    def build(self):
        Builder.load_string(KV)
        self.screen = None
        self.root = FloatLayout()
        self.screen_layout = FloatLayout()
        self.menu = ScreenMenu()
        self.root.add_widget(self.screen_layout)
        self.root.add_widget(self.menu)

        self.menu.bind(text=self.select_screen)
        self.show('main')
        return self.root

    def select_screen(self, *args):
        self.show(self.menu.text)

    def show(self, name='main'):
        if self.screen is not None:
            self.screen_layout.remove_widget(self.screen)
            self.screen = None
        if name == 'main':
            screen = MainScreen()
        elif name == 'help':
            screen = HelpScreen()
        elif name == 'settings':
            screen = SettingsScreen()
        else:
            raise Exception('Invalid screen name')
        self.screen = screen
        self.screen_layout.add_widget(screen)


if __name__ == "__main__":
    MyApp().run()

如您所见,这几乎与上面 link 中的代码完全相同,唯一的区别是在这里,我创建了一个 "Edit" 按钮,单击该按钮时,它指向"MainScreen" class.

的 goEdit() 方法
on_press: root.goEdit()

我的问题是我不知道如何创建 goEdit() 方法,以便在调用时转到 "EditScreen" 同时让微调器工作(它转到 "MainScreen"、"HelpScreen" 和 "SettingScreen" 屏幕)。我在 goEdit() 中尝试的代码显然不起作用。

我也试过将继承的 classes 从 FloatLayout 更改为 Screen:

class MainScreen(Screen):   
    def goEdit(self):
        self.parent.current = 'edit_Screen'         
class HelpScreen(Screen):
    pass
class SettingsScreen(Screen):
    pass
class EditScreen(Screen):
    pass
class ScreenMenu(Spinner):
    pass

我在这里尝试使用以下代码切换屏幕:

self.parent.current = 'edit_Screen'

但是当点击 'edit' 按钮时,没有任何反应,我什至没有收到错误消息。

基本上我想要的是让微调器像示例 link 中那样工作,但我还需要 'edit' 按钮来切换屏幕。任何帮助将不胜感激。

这是一个使用 ScreenManager 的非常简单的示例:

Python

import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition

class Screen1(Screen):

    pass

class Screen2(Screen):

    pass

class Screen3(Screen):

    pass

class MyScreenManager(ScreenManager):

    def changescreen(self, value):

        try:
            if value!='Choose a Value...':
                self.current = value
        except:
            print('No screen named ' + value)

#Main application
class TestApp(App):

    def build(self):
        self.sm = MyScreenManager()
        return self.sm

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

kv

<MyScreenManager>:

    Screen1:
        name: 'screen1'
    Screen2:
        name: 'screen2'
    Screen3:
        name: 'screen3'

<Screen1>:

    GridLayout:

        rows: 2
        padding: 20
        spacing: 20

        Button:
            text: 'Go to Screen 2'
            on_press: root.manager.current = 'screen2'

        Button:
            text: 'Go to Screen 3'
            on_press: root.manager.current = 'screen3'

        Spinner:
            text: 'Choose a Value...'
            values: ['screen2', 'screen3']
            on_text:
                root.manager.changescreen(self.text)
                self.text = 'Choose a Value...'

        Label:
            text: 'You are on ' + root.name

<Screen2>:

    GridLayout:

        rows: 2
        padding: 20
        spacing: 20

        Button:
            text: 'Go to Screen 1'
            on_press: root.manager.current = 'screen1'

        Button:
            text: 'Go to Screen 3'
            on_press: root.manager.current = 'screen3'

        Spinner:
            text: 'Choose a Value...'
            values: ['screen1', 'screen3']
            on_text:
                root.manager.changescreen(self.text)
                self.text = 'Choose a Value...'

        Label:
            text: 'You are on ' + root.name

<Screen3>:

    GridLayout:

        rows: 2
        padding: 20
        spacing: 20

        Button:
            text: 'Go to Screen 1'
            on_press: root.manager.current = 'screen1'

        Button:
            text: 'Go to Screen 2'
            on_press: root.manager.current = 'screen2'

        Spinner:
            text: 'Choose a Value...'
            values: ['screen1', 'screen2']
            on_text:
                root.manager.changescreen(self.text)
                self.text = 'Choose a Value...'

        Label:
            text: 'You are on ' + root.name

解决方案

详情请参考解释、示例和输出。

kv 字符串

  1. root.edit()替换为app.show(name='edit')
  2. 名称:'edit_screen'替换为标签:
  3. 缩进 文本:'Edit Screen'

Python 脚本

  1. MainScreen中的所有编码替换为pass
  2. 在方法show
  3. 中添加elif name=='edit':screen=EditScreen()语句

例子

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.spinner import Spinner

KV = """
<MainScreen>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text: 'Edit'
            on_press: app.show(name='edit')
        Label:
            text: 'Main Screen'

<HelpScreen>:
    Label:
        text: 'Help Screen'

<SettingsScreen>:
    Label:
        text: 'Settings Screen'

<EditScreen>:
    Label:
        text: 'Edit Screen'

<ScreenMenu>:
    text: 'main'
    values: ('main', 'help', 'settings')
    size_hint: None, None
    size: 200, 44
"""


class MainScreen(FloatLayout):
    pass


class HelpScreen(FloatLayout):
    pass


class SettingsScreen(FloatLayout):
    pass


class EditScreen(FloatLayout):
    pass


class ScreenMenu(Spinner):
    pass


class MyApp(App):

    def build(self):
        Builder.load_string(KV)
        self.screen = None
        self.root = FloatLayout()
        self.screen_layout = FloatLayout()
        self.menu = ScreenMenu()
        self.root.add_widget(self.screen_layout)
        self.root.add_widget(self.menu)

        self.menu.bind(text=self.select_screen)
        self.show('main')
        return self.root

    def select_screen(self, *args):
        self.show(self.menu.text)

    def show(self, name='main'):
        if self.screen is not None:
            self.screen_layout.remove_widget(self.screen)
            self.screen = None
        if name == 'main':
            screen = MainScreen()
        elif name == 'help':
            screen = HelpScreen()
        elif name == 'settings':
            screen = SettingsScreen()
        elif name == 'edit':
            screen = EditScreen()
        else:
            raise Exception('Invalid screen name')
        self.screen = screen
        self.screen_layout.add_widget(screen)


if __name__ == "__main__":
    MyApp().run()

输出