从 Kivy 的另一个屏幕更改小部件

Posted

技术标签:

【中文标题】从 Kivy 的另一个屏幕更改小部件【英文标题】:Changing widget from another screen in Kivy 【发布时间】:2020-08-12 23:49:48 【问题描述】:

我正在尝试通过 Kivy 另一个视图中的按钮更新一个小部件。

基维码:

<MainScreen>:
    relatorios : relatorios
    despesas : despesas
    GridLayout:
        size: root.width, root.height
        cols : 1
        Button:
            id: relatorios
            text: 'Relatorios'
            on_press: root.change_screen(rep = 'Report')
        Button:
            id: despesas
            text:  'Despesa'
            on_press: root.change_screen(rep = 'Expend')

<ReportScreen>:
    GridLayout:
        size: root.width, root.height
        cols : 1
        Button:
            id: semanal
            text: 'Semanal'
        Button:
            id: mensal
            text:  'Mensal'
        Button:
            id: anual
            text:  'Anual'
        Button:
            id: voltar
            text:  'Voltar'
            on_press: root.change_screen(rep = 'Main')

<ExpendScreen>:
    kind_selec1 : kind_select
    GridLayout:
        size: root.width, root.height
        cols : 2
        Label:
            id: kind
            text: 'Tipo de Despesa'
        Button:
            id: kind_select
            text:  'Selecionar'
            on_press: root.change_screen(rep = 'Kind')
        Label:
            id: way
            text:  'Meio de Pagamento'
        Button:
            id: selec_way
            text:  'Selecionar'
            on_press: root.change_screen(rep = 'Way')
        Label:
            id: parcelas
            text:  'Quantidade de Parcelas'
        TextInput:
            id: qtdy
        Label:
            id: value
            text:  'Valor Total'
        TextInput:
            id: qtdy
        Button:
            id: back
            text:  'Voltar'
            on_press: root.change_screen(rep = 'Main')
        Button:
            id: submit
            text:  'Registrar'
            on_press: root.change_name()

<DropDown1>:
    cols : 1
    orientation: 'vertical'

<DropDown2>:
    cols : 1
    orientation: 'vertical'

Python 代码:

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from functools import partial
from functions import Expense
from kivy.properties import ObjectProperty
import kivy
import time

class MainScreen(Widget):
    relatorios = ObjectProperty(None)
    despesas = ObjectProperty(None)

    def change_screen(self,rep):
        app_finan_con.screen_manager.current = rep
        return


class ReportScreen(Widget):
    def change_screen(self,rep):
        app_finan_con.screen_manager.current = rep
        return

class ExpendScreen(Widget):
    kind_selec1 = ObjectProperty()

    def __init__(self, **kwargs):
        super(ExpendScreen, self).__init__(**kwargs)
    def change_screen(self,rep):
        app_finan_con.screen_manager.current = rep
    def change_name(self):
        self.kind_selec1.text= 'porra'


class Dropdown1(BoxLayout):
    def __init__(self, **kwargs):
        super(Dropdown1, self).__init__(**kwargs)
        list = ['Alimentação', 'Transporte', 'Entretenimento','Moradia','Doação']
        for item in list:
            self.but = Button(text=item)
            self.add_widget(self.but)
            self.but.bind(on_release=partial(self.It,arg = item))

    def It(self,instance,arg):
        app_finan_con.screen_manager.current = 'Expend'
        ExpendScreen.change_name(ExpendScreen)


class Dropdown2(BoxLayout):
    def __init__(self, **kwargs):
        super(Dropdown2, self).__init__(**kwargs)
        list = ['Crédito', 'Débito', 'Dinheiro']
        for item in list:
            self.but = Button(text=item)
            self.add_widget(self.but)
            self.but.bind(on_release=partial(self.It, arg=item))

    def It(self,instance,arg):
        app_finan_con.screen_manager.current = 'Expend'



class MyApp(App):

    def build(self):
        self.screen_manager = ScreenManager()

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

        self.reportscreen = ReportScreen()
        screen = Screen(name='Report')
        screen.add_widget(self.reportscreen)
        self.screen_manager.add_widget(screen)

        self.expendscreen = ExpendScreen()
        screen = Screen(name='Expend')
        screen.add_widget(self.expendscreen)
        self.screen_manager.add_widget(screen)

        self.dropdown1 = Dropdown1()
        screen = Screen(name='Kind')
        screen.add_widget(self.dropdown1)
        self.screen_manager.add_widget(screen)

        self.dropdown2 = Dropdown2()
        screen = Screen(name='Way')
        screen.add_widget(self.dropdown2)
        self.screen_manager.add_widget(screen)

        return self.screen_manager

def change_screen():
    app_finan_con.screen_manager.current ='Report'
    return


if __name__ == '__main__':
    app_finan_con = MyApp()
    app_finan_con.run()

思路是使用screen Dropdown1通过这段代码修改screen ExpendScreen:

class Dropdown1(BoxLayout):
    def __init__(self, **kwargs):
        super(Dropdown1, self).__init__(**kwargs)
        list = ['Alimentação', 'Transporte', 'Entretenimento','Moradia','Doação']
        for item in list:
            self.but = Button(text=item)
            self.add_widget(self.but)
            self.but.bind(on_release=partial(self.It,arg = item)) (this line activates It method)

    def It(self,instance,arg):  
        app_finan_con.screen_manager.current = 'Expend'
        ExpendScreen.change_name(ExpendScreen) (this line activates method in ExpendScreen):

class ExpendScreen(Widget):
    kind_selec1 = ObjectProperty()

    def __init__(self, **kwargs):
        super(ExpendScreen, self).__init__(**kwargs)
    def change_screen(self,rep):
        app_finan_con.screen_manager.current = rep
    def change_name(self):
        self.kind_selec1.text= 'porra'

但我收到以下错误:AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'text'

但是当我从同一屏幕 (ExpendScreen) 中的按钮调用相同的方法时,它按预期工作,kivy 代码:

Button:
   id: submit
   text:  'Registrar'
   on_press: root.change_name()

图片示例:

谁能帮帮我?

【问题讨论】:

【参考方案1】:

你的代码行:

ExpendScreen.change_name(ExpendScreen) 

在没有实例的情况下调用ExpendScreen 的实例方法。那是行不通的。您需要获取属于您的 gui 的 ExpendScreen 的实例,并调用其 change_name 方法。我没有对此进行测试,但我认为将上面的行替换为:

app_finan_con.expendscreen.change_name()

会做你想做的。

【讨论】:

以上是关于从 Kivy 的另一个屏幕更改小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何传递一个值来初始化 Kivy 中的屏幕小部件?

如何将位于同一行的 Kivy 小部件移得更远?

使用python / kivy处理小部件放置以解决屏幕旋转的好方法是啥?

更改 Kivy 小部件部分文本的颜色

如何在 Kivy 屏幕小部件中初始化实例

Kivy 模块开关小部件在任何地方按下