Kivy 在另一个类中调用函数

Posted

技术标签:

【中文标题】Kivy 在另一个类中调用函数【英文标题】:Kivy Calling function in another class 【发布时间】:2022-01-08 11:39:56 【问题描述】:

我已经被这个问题困扰了一段时间,所以我在这里。我正在尝试通过屏幕管理器在 python 类中调用一个函数,但我不知道这是否是最好的方法。

这是我的代码,用于一个最低限度的可生产示例:

from kivymd.uix.screen import MDScreen
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout


Builder.load_file('TestKV.kv')
class Welcome(Screen):
    def __init__(self, **kwargs):
        super(Welcome, self).__init__(**kwargs)
        pass

    def MoveOn(self):
        self.manager.screens[1].TestCallback()

class TestTabs(TabbedPanel):
    def __init__(self, **kwargs):
        super(TestTabs, self).__init__(**kwargs)
        
        pass

    def TestCallback():
        print("Success")

class TestScreen(Screen):
    def __init__(self, **kwargs):
        super(TestScreen, self).__init__(**kwargs)
        self.add_widget(TestTabs())
        pass

class ExampleApp(MDApp):
    def build(self):
        self.sm = ScreenManager(transition=NoTransition())
        self.sm.add_widget(Welcome(name="Welcome"))
        self.sm.add_widget(TestScreen(name="Stack"))

        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "DeepOrange"
        return self.sm


ExampleApp().run()

还有我的 Kivy 文件:

<Welcome>
    Screen:
        MDCard:
            size_hint: None, None
            size: 300, 400
            pos_hint:"center_x": 0.5, "center_y": 0.5
            elevation: 10
            padding:25
            spacing: 25
            orientation: "vertical"

            MDRoundFlatButton:
                text:"Go To Next Screen"
                on_press: root.MoveOn()


<Test1@TabbedPanelItem>
    BoxLayout:
        ScrollView:
            do_scroll_x: False  # Important for MD compliance
            do_scroll_y:True
            size_hint_x: 0.35
            MDList:
                id:tasks
                size_hint: None, None
                size: 300, 400
                pos_hint:"center_x": 0.5, "center_y": 0.5
                padding:25
                spacing: 25

        ScrollView:
            do_scroll_x:False
            do_scroll_y:True
            pos_hint:"center_x": 0.5, "center_y": 0.5
            size_hint_x: 0.5
            width : 400
            padding:25
            spacing:25
            BoxLayout:
                size_hint_y : None
                height: self.minimum_height
                elevation: 10
                padding: (0, 50, 0,0)
                spacing: 50
                orientation:'vertical'
                Label:
                    text:'Basic Information'
                    font_size:18
                MDTextField:
                    id:basic
                    size_hint_x: None
                    width: 200
                    height: 100
                    font_size: 18
                    pos_hint: "center_x": 0.5
                    multiline:False
                    max_text_length: 15

<TestTabs>:

    id:testTabs
    pos_hint: 'center_x': .5, 'center_y': .5
    do_default_tab: False

    Test1:
        id:test1

我正在尝试在一个屏幕上按下按钮,在另一个屏幕的子项(选项卡式面板的子项)上调用该函数。

请帮忙,因为我不知道出了什么问题。

【问题讨论】:

【参考方案1】:

TestCallback() 方法是 TestTabs 类的方法,因此您需要引用 TestTabs 实例才能调用其 TestCallback() 方法。

一种方法是在创建 TestTabs 实例时保存对它的引用:

class TestScreen(Screen):
    def __init__(self, **kwargs):
        super(TestScreen, self).__init__(**kwargs)
        self.testTabs = TestTabs()  # save a reference to the TestTabs instance
        self.add_widget(self.testTabs)

然后,使用该引用调用TestCallback() 方法:

def MoveOn(self):
    # self.manager.screens[1].testTabs.TestCallback()
    self.manager.get_screen('Stack').testTabs.TestCallback()

使用get_screen() 方法不如使用Screens 列表中的索引那么脆弱。此外,TestCallback() 方法需要 self 参数:

def TestCallback(self):
    print("Success")

除非您将TestCallback() 定义为static 方法(无self 参数)。

【讨论】:

如果我将 TestCallback 函数放到 Test1 类中会怎样? 这只是让访问函数有点复杂。

以上是关于Kivy 在另一个类中调用函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个类中调用一个类中的函数对象?

(Kivy) 从 App 类调用函数 - 函数对象没有属性

如何在另一个类中使用带有构造函数的类?

在另一个类c ++中调用成员函数

Jasmine:在另一个类中测试静态函数

在另一个类中调用一个类的成员