python - Kivy中如何通过函数实现到新Screen的转换?

标签 python python-3.x kivy kivy-language

我想在单击按钮后实现到新屏幕的转换,并且我想通过该函数来完成此操作。 我有这个kv代码

<ScreenFrame@BoxLayout>:
    orientation: 'vertical'
    cols: 3

    ActionBar:
        ActionView:
            pos_hint: {'top':1}
            use_separator: True
            ActionPrevious:
                title: "Title"
                with_previous: False
            ActionButton:
                text: "+"


    Label:
        text: "Content"


    BoxLayout:
        orientation: 'horizontal'
        cols: 4
        size_hint: 1, 0.15

        Button:
            text: "Notes"
            #don't work
            on_press: root.manager.current = 'nts'
        Button:
            text: "Docs"
            #don't work
            on_release: root.go_to_dcs()

        Button:
            text: "Videos"
            #don't work
            on_release: root.manager.current = "vds"
        Button:
            text: "Pictures"
            # don't work
            on_release: root.manager.current = 'pctrs'

<NtsScreen>:
    BoxLayout:
        orientation: "vertical"
        cols: 2

        ScreenFrame:
        Button:
            text: "f"
            #work, but me need implementaion through function
            on_press: root.manager.current = "vds"

<DocsScreen>:
    ScreenFrame:

<VdsScreen>:
    ScreenFrame:

<PctrsScreen>:
    ScreenFrame:

和这个文件

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.properties import StringProperty
from kivy.uix.widget import Widget


Builder.load_file("main.kv")

class ScreenFrame():
    def go_to_dcs(self):
        sm.current = "dcs"

class NtsScreen(Screen):
    pass

class DcsScreen(Screen):
    def go_to_dcs(self):
        sm.current = 'dcs'

class VdsScreen(Screen):
    pass

class PctrsScreen(Screen):
    pass


# Create the screen manager
sm = ScreenManager()
sm.add_widget(NtsScreen(name='nts'))
sm.add_widget(DcsScreen(name='dcs'))
sm.add_widget(VdsScreen(name='vds'))
sm.add_widget(PctrsScreen(name='pctrs'))


class MainApp(App):
    def build(self):
        return sm

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

,但是当我运行并按“文档”按钮时出现此错误

 Traceback (most recent call last):
   File "main.py", line 45, in <module>
     MainApp().run()
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/app.py", line 826, in run
     runTouchApp()
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/base.py", line 502, in runTouchApp
     EventLoop.window.mainloop()
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/core/window/window_pygame.py", line 403, in mainloop
     self._mainloop()
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/core/window/window_pygame.py", line 289, in _mainloop
     EventLoop.idle()
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/base.py", line 340, in idle
     self.dispatch_input()
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/base.py", line 325, in dispatch_input
     post_dispatch_input(*pop(0))
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/base.py", line 291, in post_dispatch_input
     wid.dispatch('on_touch_up', me)
   File "kivy/_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/uix/behaviors/button.py", line 179, in on_touch_up
     self.dispatch('on_release')
   File "kivy/_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
   File "kivy/_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
   File "kivy/_event.pyx", line 1098, in kivy._event.EventObservers._dispatch
   File "/home/parvektor228/TAOKF/lib/python3.6/site-packages/kivy/lang/builder.py", line 64, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "/home/parvektor228/TAOKF/KivyApp/memfier/main.kv", line 32, in <module>
     on_release: root.go_to_dcs()
   File "kivy/weakproxy.pyx", line 30, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'ScreenFrame' object has no attribute 'go_to_dcs'

错误在哪里或者我有什么不明白的地方吗?

更多细节,以便错误通知消失。 更多细节,以便错误通知消失。 更多细节,以便错误通知消失。

最佳答案

问题 - 属性错误

有两个 AttributeErrors,它们如下:

属性错误:go_to_dcs(​​)方法

     on_release: root.go_to_dcs()
   File "kivy/weakproxy.pyx", line 30, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'ScreenFrame' object has no attribute 'go_to_dcs'

在 kv 文件中,dynamic class , <ScreenFrame@BoxLayout>:被定义为没有 go_to_dcs()方法已实现。

属性错误:经理

     on_press: root.manager.current = 'nts'
   File "kivy/weakproxy.pyx", line 30, in kivy.weakproxy.WeakProxy.__getattr__
 AttributeError: 'ScreenFrame' object has no attribute 'manager'

动态类,<ScreenFrame@BoxLayout>:具有 BoxLayout 继承,但没有 Screen 继承。因此,它没有名为manager的属性。

解决方案

kv 文件

  1. 替换动态类,<ScreenFrame@BoxLayout>:与类(Class)规则,<ScreenFrame>:
  2. 在类(class)规则中,<ScreenFrame>: - 替换root.manager.currentapp.root.current

代码片段

<ScreenFrame>:

        Button:
            text: "Notes"
            on_press: app.root.current = 'nts'
        Button:
            text: "Docs"
            on_release: root.go_to_dcs()    
        Button:
            text: "Videos"
            on_press: app.root.current = 'vds'
        Button:
            text: "Pictures"
            on_press: app.root.current = 'pctrs'

Kv language » Three Keywords

There are three keywords specific to Kv language:

app: always refers to the instance of your application.

root: refers to the base widget/template in the current rule

self: always refer to the current widget

Python 代码

  1. 添加导入语句,from kivy.uix.boxlayout import BoxLayout
  2. 替换class ScreenFrame():class ScreenFrame(BoxLayout):

示例

main.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder


Builder.load_file("main.kv")


class ScreenFrame(BoxLayout):
    def go_to_dcs(self):
        print("\nScreenFrame.go_to_dcs")
        sm.current = "dcs"


class NtsScreen(Screen):
    pass


class DcsScreen(Screen):
    def go_to_dcs(self):
        sm.current = 'dcs'


class VdsScreen(Screen):
    pass


class PctrsScreen(Screen):
    pass


# Create the screen manager
sm = ScreenManager()
sm.add_widget(NtsScreen(name='nts'))
sm.add_widget(DcsScreen(name='dcs'))
sm.add_widget(VdsScreen(name='vds'))
sm.add_widget(PctrsScreen(name='pctrs'))


class MainApp(App):
    def build(self):
        return sm


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

main.kv

#:kivy 1.11.0

<ScreenFrame>:
    orientation: 'vertical'
    cols: 3

    ActionBar:
        ActionView:
            pos_hint: {'top':1}
            use_separator: True
            ActionPrevious:
                title: "Title"
                with_previous: False
            ActionButton:
                text: "+"


    Label:
        text: "Content"


    BoxLayout:
        orientation: 'horizontal'
        cols: 4
        size_hint: 1, 0.15

        Button:
            text: "Notes"
            on_press: app.root.current = 'nts'

        Button:
            text: "Docs"
            on_release: root.go_to_dcs()

        Button:
            text: "Videos"
            on_press: app.root.current = 'vds'

        Button:
            text: "Pictures"
            on_press: app.root.current = 'pctrs'

<NtsScreen>:
    BoxLayout:
        orientation: "vertical"
        cols: 2

        ScreenFrame:
        Button:
            text: "f"
            #work, but me need implementaion through function
            on_press: root.manager.current = "vds"

<DcsScreen>:
    ScreenFrame:

<VdsScreen>:
    ScreenFrame:

<PctrsScreen>:
    ScreenFrame:

输出

Img01 - App Startup Img02 - Videos Screen Img03 - Dcs Screen

关于python - Kivy中如何通过函数实现到新Screen的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51620484/

相关文章:

Python 验证 Web 表单数据

python - 为人类可读性保存 Pandas 描述

python - 修改冷却装饰器以用于方法而不是函数

Python/Kivy 初始变量赋值

python - 当新字符串替换旧字符串时如何更改标签的字体大小

python - 按列对 pandas 数据帧进行阈值化

python - Pandas:知道操作何时影响原始数据帧

python - 多行正则表达式与迭代器兼容吗?

python - 为整个存储库动态创建测试文件模板

python - Kivy - 使用 .kv