如何使用 kivy 在不同的 python 文件中从另一个屏幕更新一个屏幕

问题描述 投票:0回答:1

如果大型项目需要多个屏幕,我必须将每个屏幕放入一个 python 文件中,然后在一个 main.py 文件中调用它们。但是如何从一个屏幕上更改另一个屏幕上的元素呢?在这个例子中,如果登录屏幕在login.py文件中,主屏幕在home.py文件中,如何从login.py屏幕更改home.py屏幕中的标签?

主.py

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

from login import LoginScreen
from home import HomeScreen

Builder.load_string(
"""
<ManagerScreen>:
    Screen:
        id: login
        name: 'login'
    MDScreen:
        id: register
        name: 'register'
    Screen:
        id: home
        name: 'home'

""" )

class ManagerScreen(ScreenManager):
    def __init__(self, **kwargs):
        super(ManagerScreen, self).__init__(**kwargs)
        self.ids.login.add_widget(LoginScreen())
        self.ids.home.add_widget(HomeScreen())


class MainApp(MDApp):
    def build(self):
        sm = ManagerScreen()
        return sm

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

登录.py

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
import sqlite3
from loading import LoadImage

Builder.load_string(
"""
<LoginScreen>:
    MDCard:
        size_hint: .5, .4
        pos_hint: {'center_x':.5, 'center_y':.5}
        orientation: 'vertical'
        padding: 10
        spacing: 10
        MDTextField:
            id: username
            hint_text: "Nom d'utilisateur"
        MDTextField:
            id: pwd
            hint_text: "Mot de passe"
        MDRaisedButton:
            text: 'Connexion'
            pos_hint: {'center_x':.5}
            on_press: root.log_in()
        MDTextButton:
            text: "Créez un compte si vous n'en avez pas!"
            pos_hint: {'center_x':.5}
            on_press: root.parent.parent.current = 'register'
"""
    )

#class HomeScreen(MDBoxLayout):
    #pass


class LoginScreen(MDRelativeLayout):
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)

    def log_in(self):

        home_screen = self.parent.manager.get_screen('home')
        home_screen.update()
        self.parent.parent.current = 'home'

home.py

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

import sqlite3
from loading import LoadImage

Builder.load_string(
"""
#:import utils kivy.utils
<HomeScreen>:
    MDBoxLayout:
        orientation: 'vertical'
        MDBoxLayout:
            size_hint_y: None
            height: first.height
            MDRaisedButton:
                id: first
                text: "Ecran 1"
                on_press: sm.current = 'firstscreen'
            MDRaisedButton:
                id: first
                text: "Ecran 2"
                on_press: sm.current = 'secondscreen'
        ScreenManager:
            id: sm
            Screen:
                id: firstscreen
                name: 'firstscreen'
                MDRelativeLayout:
                    MDCard:
                        orientation: 'vertical'
                        md_bg_color: utils.get_color_from_hex('#3e55c9')
                        MDLabel:
                            id: lab
                            markup: True
                        MDRaisedButton:
                            id: buttontext
                            text: 'importer fichier'

            Screen:
                id: secondscreen
                name: 'secondscreen'

"""
    )


class HomeScreen(Screen):
    def __init__(self, **kwargs):
        super(HomeScreen, self).__init__(**kwargs)
        

    def update(self):
        self.ids.lab.text = "Bienvenu Monsieur"

这是我执行时他们告诉我的错误

文件“D:\MON PROJET\my test kivy ase de donnee\login.py”,第 45 行,在 log_in 中 home_screen.update() 属性错误:“屏幕”对象没有属性“更新”

我还没有找到解决这个问题的方法

python kivy kivymd
1个回答
0
投票

self.parent.manager.get_screen('home')
不是
HomeScreen
的实例,
HomeScreen
是它的子小部件
,因为您使用以下命令添加它:

self.ids.login.add_widget(LoginScreen())

例如,如果您这样做:

def log_in(self):
    home_screen = self.parent.manager.get_screen('home')
    home_screen.children[0].update()  # <<<<<<<<<<<<<<<
    self.parent.parent.current = 'home'
 

它会起作用的。

但是,您可以简单地执行以下操作,而不是将

HomeScreen
嵌套在
Screen
的另一个实例中:

from kivymd.app import MDApp
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

from login import LoginScreen
from home import HomeScreen

Builder.load_string(
"""
<ManagerScreen>:
    Screen:
        id: login
        name: 'login'
    MDScreen:
        id: register
        name: 'register'
    HomeScreen: # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
        id: home
        name: 'home'

""" )

class ManagerScreen(ScreenManager):
    def __init__(self, **kwargs):
        super(ManagerScreen, self).__init__(**kwargs)
        self.ids.login.add_widget(LoginScreen())
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


class MainApp(MDApp):
    def build(self):
        sm = ManagerScreen()
        return sm

if __name__ == '__main__':
    MainApp().run()
© www.soinside.com 2019 - 2024. All rights reserved.