您如何使用 Kivy GUI 访问其他类方法和函数?

Posted

技术标签:

【中文标题】您如何使用 Kivy GUI 访问其他类方法和函数?【英文标题】:How do you access other class methods and functions using Kivy GUI? 【发布时间】:2020-11-22 19:06:15 【问题描述】:

我正在使用 python 和 kivy 编写应用程序。为简单起见,我想找到一种在屏幕之间切换的方法,而不必在每个类中声明一个函数来转到屏幕。

例如,在我的 UserLogin 类中,我定义了一个名为 to_mainmenu 的函数,可用于返回到 EntryScreen 小部件。我想在相应 KV 文件的 MainScreen 小部件中使用该函数,特别是对于显示“选项”的按钮,但因为它是在另一个类中声明的,所以我不知道在该 kv 中调用 to_mainmenu 的语法文件。我怎么称呼它?

下面是python代码:

import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty


kivy.require('1.11.1')


class EntryScreen(GridLayout):

    def to_newuser(self):
        main_app.screen_manager.current = 'New Account'
        # yes

    def to_userlogin(self):
        main_app.screen_manager.current = 'User Login'

    def to_mainmenu(self):
        main_app.screen_manager.current = 'Main Screen'


class UserLogin(GridLayout):
    name1 = ObjectProperty(None)
    password1 = ObjectProperty(None)

    def to_entryscreen(self):
        main_app.screen_manager.current = 'Entry Screen'

    def to_login(self):
        main_app.screen_manager.current = 'Login Screen'

    def to_mainscreen(self):
        main_app.screen_manager.current = 'Main Screen'


class NewAccount(GridLayout):
    def to_mainmenu(self):
        main_app.screen_manager.current = 'Main Screen'


class MainScreen(GridLayout):
    pass


class MapGem(App):
    def build(self):
        self.screen_manager = ScreenManager()

        self.entry_screen = EntryScreen()
        screen = Screen(name='Entry Screen')
        screen.add_widget(self.entry_screen)
        self.screen_manager.add_widget(screen)

        self.user_login = UserLogin()
        screen = Screen(name='User Login')
        screen.add_widget(self.user_login)
        self.screen_manager.add_widget(screen)

        self.new_account = NewAccount()
        screen = Screen(name='New Account')
        screen.add_widget(self.new_account)
        self.screen_manager.add_widget(screen)

        self.mainscreen = MainScreen()
        screen = Screen(name='Main Screen')
        screen.add_widget(self.mainscreen)
        self.screen_manager.add_widget(screen)

        return self.screen_manager


if __name__ == '__main__':
    main_app = MapGem()
    main_app.run()

下面是kivy文件

<EntryScreen>
    cols: 1
    
    Button:
        text: 'New User'
        on_press: root.to_newuser()
        
    Button:
        text: 'Login'
        on_press: root.to_userlogin()
        
    Button:
        text: 'Skip Login'
        on_press:
            #root.manager.transition.direction = 'right'
            root.to_mainmenu()
        

<UserLogin>
    name1: name
    password1: password
    cols: 2

    Label:
        text: 'Login to Account'

    Label:
        text: ''
    
    Label:
        text: 'Username'

    TextInput:
        id: name
        multiline: False
        
    Label:
        text: 'Password'

    TextInput:
        id: password
        multiline: False
        password: True
        
    Button:
        text: 'Submit'
        on_press: root.to_mainscreen()
    Button:
        text: 'Go back to Entry Screen'
        on_press: root.to_entryscreen()


<NewAccount>
    cols: 2
    Label:
        text: 'Create New Account'
    Label:
        text: ''
        
    Label:
        text: 'Username'

    TextInput:
        multiline: False
    
    Label:
        text: 'Password'

    TextInput:
        multiline: False
        password: True

    Button:
        text: 'Submit'
        on_press: root.to_mainmenu()
    

<MainScreen>
    cols: 1

    Button:
        text: 'Create New Maps'

    Button:
        text: 'View Maps'

    Button:
        text: 'Options'
        # on_press: something to call UserLogin.to_entryscreen()

我仍然习惯于 kivy 如何处理 OOP 以及 root、app 和其他名称的含义。所以,我确信这是一个非常基本和简单的问题,所以如果它看起来很平凡,我提前道歉。

【问题讨论】:

【参考方案1】:

我找到了办法。我重新阅读了文档并发现我必须使用我的屏幕管理器来引用每个类的实例。所以,简单地说,我使用on_press: app.user_login.to_entryscreen() 来调用我需要的函数。完整的代码贴在下面。

Python:

import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty


kivy.require('1.11.1')


class EntryScreen(GridLayout):

    def to_newuser(self):
        main_app.screen_manager.current = 'New Account'
        # yes

    def to_userlogin(self):
        main_app.screen_manager.current = 'User Login'

    def to_mainmenu(self):
        main_app.screen_manager.current = 'Main Screen'


class UserLogin(GridLayout):
    name1 = ObjectProperty(None)
    password1 = ObjectProperty(None)

    def to_entryscreen(self):
        main_app.screen_manager.current = 'Entry Screen'

    def to_login(self):
        main_app.screen_manager.current = 'Login Screen'

    def to_mainscreen(self):
        main_app.screen_manager.current = 'Main Screen'


class NewAccount(GridLayout):
    def to_mainmenu(self):
        main_app.screen_manager.current = 'Main Screen'


class MainScreen(GridLayout):
    pass


class MapGem(App):
    def build(self):
        self.screen_manager = ScreenManager()

        self.entry_screen = EntryScreen()
        screen = Screen(name='Entry Screen')
        screen.add_widget(self.entry_screen)
        self.screen_manager.add_widget(screen)

        self.user_login = UserLogin()
        screen = Screen(name='User Login')
        screen.add_widget(self.user_login)
        self.screen_manager.add_widget(screen)

        self.new_account = NewAccount()
        screen = Screen(name='New Account')
        screen.add_widget(self.new_account)
        self.screen_manager.add_widget(screen)

        self.mainscreen = MainScreen()
        screen = Screen(name='Main Screen')
        screen.add_widget(self.mainscreen)
        self.screen_manager.add_widget(screen)

        return self.screen_manager


if __name__ == '__main__':
    main_app = MapGem()
    main_app.run()

KV:

<EntryScreen>
    cols: 1
    
    Button:
        text: 'New User'
        on_press: root.to_newuser()
        
    Button:
        text: 'Login'
        on_press: root.to_userlogin()
        
    Button:
        text: 'Skip Login'
        on_press:
            #root.manager.transition.direction = 'right'
            root.to_mainmenu()
        

<UserLogin>
    name1: name
    password1: password
    cols: 2

    Label:
        text: 'Login to Account'

    Label:
        text: ''
    
    Label:
        text: 'Username'

    TextInput:
        id: name
        multiline: False
        
    Label:
        text: 'Password'

    TextInput:
        id: password
        multiline: False
        password: True
        
    Button:
        text: 'Submit'
        on_press: root.to_mainscreen()
    Button:
        text: 'Go back to Entry Screen'
        on_press: root.to_entryscreen()


<NewAccount>
    cols: 2
    Label:
        text: 'Create New Account'
    Label:
        text: ''
        
    Label:
        text: 'Username'

    TextInput:
        multiline: False
    
    Label:
        text: 'Password'

    TextInput:
        multiline: False
        password: True

    Button:
        text: 'Submit'
        on_press: root.to_mainmenu()
    

<MainScreen>
    cols: 1

    Button:
        text: 'Create New Maps'

    Button:
        text: 'View Maps'

    Button:
        text: 'Options'
        on_press: app.user_login.to_entryscreen()

【讨论】:

以上是关于您如何使用 Kivy GUI 访问其他类方法和函数?的主要内容,如果未能解决你的问题,请参考以下文章

Kivy,python:如何从根类(FaceRecApp)访问外部/子类?

为啥我的 kivy 程序没有从另一个类调用函数?

python - kivy:从另一个类调用函数

Kivy - 屏幕管理器 - 访问其他类中的属性

使用 Kivy 访问类变量

Kivy - 在其他屏幕中创建的访问实例