Python Kivy。如何将标签文本更改为已按下按钮上的文本?

时间:2018-08-09 09:00:23

标签: python kivy

我有一些按钮,如果我按一下按钮-屏幕会发生变化,并且在新屏幕上有一个标签,显示已被按下的按钮上的文本。

一切正常时,它不起作用。

Python

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.lang import Builder
from kivy.uix.button import Button


class ScreenOne(Screen):
    pass

class ScreenTwo(Screen):
    def on_pre_enter(self, *args):
        btn = Button(text = "word is here", on_release =self.pressedFunction)
        self.ids.container.add_widget(btn)

        btn1 = Button(text = "another word is here", on_release =self.pressedFunction)
        self.ids.container.add_widget(btn1)

    def pressedFunction(self, instance, *args):
        self.manager.current= "three"

        screenThree = ScreenThree()
        text = str(instance.text)

        screenThree.changing_label(text)

class ScreenThree(Screen):
    def changing_label(self, text):
        self.ids.my_label.text = text

class ScreenManagement(ScreenManager):
    pass

presentation = Builder.load_file("example.kv")

class MainApp(App):
    def build(self):
        return presentation

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

Kivy

ScreenManagement:
    ScreenOne:
    ScreenTwo:
    ScreenThree:

<ScreenOne>:
    BoxLayout:
        Button:
            text: "press me"
            on_release: app.root.current = "two"

<ScreenTwo>:    
    name: "two"

    BoxLayout:
        id: container


<ScreenThree>:
    name: "three"

    BoxLayout:
        id: labelContainer

        Label:
            text: ""

输出

File "example.py", line 28, in changing_label
 self.ids.my_label.text = text
File "kivy\properties.pyx", line 841, in     kivy.properties.ObservableDict.__getattr__
 AttributeError: 'super' object has no attribute '__getattr__'

2 个答案:

答案 0 :(得分:0)

.kv文件中不存在“ my_label”,请在您要进行这些更改的标签上添加一个ID。

<ScreenThree>:
    name: "three"

    BoxLayout:
        id: labelContainer

        Label:
            id: my_label
            text: ""

答案 1 :(得分:0)

问题

1。 AttributeError-my_label

在kv文件中,缺少id: my_label

2。在填充my_label.text

之前切换屏幕

my_label.text的切换是在切换屏幕self.manager.current = "three"后完成的。

3。屏幕三-空白/黑色窗口

ScreenThree 实例化了两次。第一个实例是由ScreenThree:在kv文件中创建的(相当于Python代码中的ScreenThree())。第二个实例是用Python代码screenThree = ScreenThree()创建的。

my_label.text的填充位于第二个实例/对象中,而不是第一个实例中。因此,ScreenThree是空白/黑色窗口,因为应用程序按照kv文件(即ScreenThree的第一个实例)使用视图。

注意:

如果添加id()功能,它将在屏幕上显示不同的存储位置。

def pressedFunction(self, instance, *args):
    self.manager.current = "three"

    self.debug()

    screenThree = ScreenThree()

    print("screenThree={0}, id(screenThree)={1}".format(screenThree, id(screenThree)))

    self.debug()

    text = str(instance.text)
    screenThree.changing_label(text)

def debug(self):
    print("\ndebug:")
    print("\tself.manager.screen_names=", self.manager.screen_names)
    print("\tself.manager.screens=", self.manager.screens)
    for x in self.manager.screens:
        print("\t\tscreen={0}, id(screen)={1}".format(x, id(x)))

解决方案

kv文件

  1. id: screen_two下添加ScreenTwo:。这将用于引用ScreenTwo中的类属性/方法。
  2. app.root.current = "two"替换root.manager.current = "two",因为默认情况下每个屏幕都具有属性manager
  3. id: my_label下添加Label:

Python代码

  1. 添加导入语句from kivy.properties import StringProperty
  2. 在ScreenTwo(),text = StringProperty('')类中声明StringProperty,因此不需要传递参数和封装。
  3. 在pressedFunction()方法中,将text = str(instance.text)替换为self.text = str(instance.text)
  4. 在切换屏幕之前填充文字
  5. 在ScreenThree()类中,将changing_label()方法重命名为on_pre_enter()方法,然后从参数列表中删除text
  6. 替换self.ids.my_label.text = text' with self.ids.my_label.text = self.manager.ids.screen_two.text`
  7. 可选: 减少使用的内存,将return presentation替换为return Builder.load_file("example.kv"),然后删除presentation = Builder.load_file("example.kv")

示例

main.py

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.properties import StringProperty


class ScreenOne(Screen):
    pass


class ScreenTwo(Screen):
    text = StringProperty('')

    def on_pre_enter(self, *args):
        print("\nScreenTwo.on_pre_enter:")

        btn = Button(text = "word is here", on_release =self.pressedFunction)
        self.ids.container.add_widget(btn)

        btn1 = Button(text = "another word is here", on_release =self.pressedFunction)
        self.ids.container.add_widget(btn1)

    def pressedFunction(self, instance, *args):
        self.text = str(instance.text)      # populate before switching screen
        self.manager.current = "three"  # switch screen


class ScreenThree(Screen):
    def on_pre_enter(self, *args):
        self.ids.my_label.text = self.manager.ids.screen_two.text


class ScreenManagement(ScreenManager):
    pass


class MainApp(App):
    def build(self):
        return Builder.load_file("example.kv")


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

example.kv

#:kivy 1.11.0

ScreenManagement:
    ScreenOne:
    ScreenTwo:
        id: screen_two
    ScreenThree:

<ScreenOne>:
    BoxLayout:
        Button:
            text: "press me"
            on_release: root.manager.current = "two"    # every screen has a default property manager

<ScreenTwo>:
    name: "two"

    BoxLayout:
        id: container


<ScreenThree>:
    name: "three"

    BoxLayout:
        id: labelContainer

        Label:
            id: my_label
            text: ""

输出

Img01 - ScreenTwo Img02 - ScreenThree Button1's Text displayed Img03 - ScreenThree Button2's Text displayed