简体   繁体   English

Kivy 从屏幕管理器访问 class 属性

[英]Kivy accessing class attributes from screen manager

I am using python and kivy to make a simple app, but when I create multiple screen for my app, I cannot access the class attributes of some class.我正在使用 python 和 kivy 来制作一个简单的应用程序,但是当我为我的应用程序创建多个屏幕时,我无法访问某些 class 属性。

I have problem accessing a method using screen manager.我在使用屏幕管理器访问方法时遇到问题。

main.py主文件

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


class MyGame(Widget):
    def __init__(self, **kwargs):
        super(MyGame, self).__init__(**kwargs)

    def print_a_word(self):
        print('a word')

class OptionWindow(Screen):
    pass


class SecondWindow(Screen):
    pass


class WindowManager(ScreenManager):
    pass

kv = Builder.load_file('screen_manager.kv')

class MyMainApp(App):
    def build(self):
        return kv

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

kivy file (screen_manager.kv) kivy 文件 (screen_manager.kv)

#:kivy 2.0.0
# File name: screen_manager.kv
#: import MyGame Widget

WindowManager:

    OptionWindow:
    SecondWindow:

<OptionWindow>:
    name: "main"

    GridLayout:
        cols:1
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1
            Rectangle:
                pos: 0, 0
                size: root.width, root.height
        GridLayout:
            rows: 5
            padding: 50, 50
            spacing: 20, 20
            OptionBtn:
                text: 'Americas'
                on_release:
                    app.root.current = "second"
                    root.manager.transition.direction = "left"



<SecondWindow>:
    name: "second"
    MyGame
    Button:
        on_press: root.MyGame.print_a_word()


<OptionBtn@Button>
    background_normal: 'Images/Other/white.png'
    color: 0, 0, 0, 1
    font_size: 20
    canvas.after:
        Color:
            rgba: 0, 0, 0, 1
        Line:
            rectangle: self.x, self.y, self.size[0], self.size[1]

Everything works well until I press on the button of the second window.一切正常,直到我按下第二个 window 的按钮。 I cannot access the method from MyGame(Widget).我无法从 MyGame(Widget) 访问该方法。 I get 'SecondWindow' object has no attribute 'MyGame'我得到'SecondWindow' object has no attribute 'MyGame'

This is part of a bigger issue because I made this file to solve my original issue which is... I have a big program in which I have two files main.py and my.kv and I want to add screens.这是一个更大问题的一部分,因为我制作这个文件是为了解决我最初的问题,即......我有一个大程序,其中有两个文件 main.py 和 my.kv,我想添加屏幕。 In this main.py, everything is defined a class that inherits from Widget and the build method returns an instance of that class.在这个 main.py 中,所有内容都定义为继承自 Widget 的 class,并且 build 方法返回该 class 的实例。 This is why I made the files from above... it is to understand how I can access from the Widget class.这就是我从上面制作文件的原因......这是为了了解我如何从小部件 class 访问。 Thank you谢谢

Here I fixed your example code now the print_my_word() method inside MyGame() object can be accessed and executed this should be enough to get you in the way.在这里,我修复了您的示例代码,现在可以访问和执行 MyGame() object 中的 print_my_word() 方法,这应该足以让您挡道。

Only the kv file needed change:只有 kv 文件需要更改:

Used include instead of import in "MyGame" object:在“MyGame”object 中使用包含而不是导入:
#: include MyGame #: 包括我的游戏

Instantiate it inside <SecondWindow> object.在 <SecondWindow> object 中实例化它。

Added an id to it, to be able to access it.为其添加了一个 ID,以便能够访问它。

WindowManager:

    OptionWindow:
    SecondWindow:

<OptionWindow>:
    name: "main"

    GridLayout:
        cols:1
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1
            Rectangle:
                pos: 0, 0
                size: root.width, root.height
        GridLayout:
            rows: 5
            padding: 50, 50
            spacing: 20, 20
            OptionBtn:
                text: 'Americas'
                on_release:
                    app.root.current = "second"
                    root.manager.transition.direction = "left"



<SecondWindow>:
    name: "second"
    MyGame:
        id: my_game
    Button:
        on_press: my_game.print_a_word()


<OptionBtn@Button>
    background_normal: 'Images/Other/white.png'
    color: 0, 0, 0, 1
    font_size: 20
    canvas.after:
        Color:
            rgba: 0, 0, 0, 1
        Line:
            rectangle: self.x, self.y, self.size[0], self.size[1]

Ok this next part below is an update to respond your question in the second comment.好的,下面的下一部分是在第二条评论中回答您的问题的更新。

main.py主文件

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


class MyGame(Widget):
    def __init__(self, **kwargs):
        super(MyGame, self).__init__(**kwargs)

    def print_a_word(self):
        print('My Game: print method')

class OptionWindow(Screen):
    pass


class SecondWindow(Screen):
    pass


class WindowManager(ScreenManager):
    pass

kv = Builder.load_file('screen_manager.kv')

class MyMainApp(App):
    def build(self):
        self.my_game = MyGame()  # <-- instantiated MyGame in the Main class to access it from any where
        return kv

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

screen_manager.kv screen_manager.kv

WindowManager:
    OptionWindow:
    SecondWindow:



<OptionWindow>:
    name: "main"

    GridLayout:
        cols:1
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1
            Rectangle:
                pos: 0, 0
                size: root.width, root.height
        GridLayout:
            rows: 5
            padding: 50, 50
            spacing: 20, 20
            OptionBtn:
                text: 'Americas'
                on_release:
                    app.root.current = "second"
                    root.manager.transition.direction = "left"
            # ADDED EXTRA BUTTON TO SAMPLE ACCESSING MyGame OBJECT, FROM THIS CLASS
            Button:
                text: 'Access My Game Method'
                on_release:
                    app.my_game.print_a_word()   # <-- app can access main class attributes and methods



<SecondWindow>:
    name: "second"
    # USE A BOXLAYOUT TO LAYOUT THE BUTTONS
    BoxLayout:
        orientation: 'vertical'
        spacing: 2
        padding: 2
        # ADDED BUTTON TO SAMPLE ACCESSING MyGame OBJECT
        Button:
            text: 'Access method from MyGame'
            on_press: app.my_game.print_a_word()     # <-- app can access main class attributes and methods
        Button:
            text: 'Return to Main'
            on_press: app.root.current = "main"



<OptionBtn@Button>
    background_normal: 'Images/Other/white.png'
    color: 0, 0, 0, 1
    font_size: 20
    canvas.after:
        Color:
            rgba: 0, 0, 0, 1
        Line:
            rectangle: self.x, self.y, self.size[0], self.size[1]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM