【问题标题】:Using a spinner and button together to change screens一起使用微调器和按钮来更改屏幕
【发布时间】:2018-04-03 19:42:54
【问题描述】:

我发现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()

如您所见,这几乎与上面链接中的代码完全相同,唯一的区别是,在这里,我创建了一个“编辑”按钮,当单击该按钮时,它引用“MainScreen”的 goEdit() 方法" 类。

on_press: root.goEdit()

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

我也尝试过将继承的类从 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'

但是当点击“编辑”按钮时,什么也没有发生,我什至没有收到错误消息。

基本上我想要的是让微调器像示例链接中那样工作,但我还需要“编辑”按钮来更改屏幕。任何帮助将不胜感激。

【问题讨论】:

  • 相反,我会考虑使用 ScreenManager 并将您的各个屏幕定义为 .kv 文件中 ScreenManager 的子屏幕。然后从每个屏幕上的按钮小部件中,您可以将 on_press 或 on_release 事件绑定为:root.manager.current = 'menu'

标签: python button kivy spinner screen


【解决方案1】:

解决方案

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

kv 字符串

  1. root.edit() 替换为 app.show(name='edit')
  2. name: 'edit_screen' 替换为 Label:
  3. 缩进文本:“编辑屏幕”

Python 脚本

  1. MainScreen中的所有编码替换为pass
  2. 在方法 show 中添加 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()

输出

【讨论】:

    【解决方案2】:

    这是一个使用 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()
    

    千伏

    <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
    

    【讨论】:

    • 感谢您的意见。我确实需要使用链接中的微调器屏幕切换方法(或其他替代方法)进行导航,并且使用单独的按钮也可以切换到不同的屏幕。
    • 编辑了我的答案以包含一个包含屏幕更改的微调器。可能有一种更有效的方法来实现这一点,但我认为这是最容易理解的例子。希望这会有所帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多