Kivy Popup 无法访问 root 方法

Posted

技术标签:

【中文标题】Kivy Popup 无法访问 root 方法【英文标题】:Kivy Popup not able to access root method 【发布时间】:2018-11-12 04:44:55 【问题描述】:

我是这里的新手,如果我没有遵循正确的程序,请随时纠正我。

我有一个 Kivy 应用程序,它会打开一个弹出窗口。在弹出窗口中,我可以输入 2 个数字,然后单击应该添加 2 个数字的添加按钮。我收到一条错误消息:“AttributeError: 'CustomPopup' 对象没有属性 'addNum'”

为什么会这样?

test.py file

import kivy
kivy.require('1.9.1') # replace with your current kivy version !

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty

class CustomPopup(Popup):
    pass

class MyStuff(BoxLayout):

    num1 = StringProperty
    num2 = StringProperty
    answer = ''

    def openPopup(self):
        the_popup = CustomPopup()
        the_popup.open()

    def addNum(self):
        self.answer = str(int(self.num1) + int(self.num2))

class MyStuffApp(App):

    def build(self):
        return MyStuff()

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

mystuff.kv 文件

#: import main test

<MyStuff>:
    orientation: 'vertical'
    spacing: 5
    padding: 5


    Button:
        text: 'Change numbers'
        on_press: root.openPopup()
        font_size: 50

    Label:
        text: root.answer


<CustomPopup>:
    size_hint: .5, .5
    auto_dismiss: False
    title: 'Addition'
    num1: number2
    num2: number2

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: '1st number'

        TextInput:
            id: number1

        Label
            text: '2nd number'

        TextInput
            id: number2

        Button:
            text: 'Add'
            on_press: root.addNum()

【问题讨论】:

【参考方案1】:

首先,要访问addNum,您必须从kv 部分调用app.root.addNum。 您还必须发送要添加的值,即您在文本框中输入的文本:(number1.text, number2.text)。 所以运行代码可能是这样的:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup

Builder.load_string("""
<MyStuff>:
    orientation: 'vertical'
    spacing: 5
    padding: 5
    Button:
        text: 'Change numbers'
        on_press: root.openPopup()
        font_size: 50

    Label:
        text: root.answer


<CustomPopup>:
    size_hint: .5, .5
    auto_dismiss: False
    title: 'Addition'
    num1: number2
    num2: number2

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: '1st number'

        TextInput:
            id: number1

        Label
            text: '2nd number'

        TextInput
            id: number2

        Button:
            text: 'Add'
            on_press: app.root.addNum(number1.text, number2.text)
""")


class CustomPopup(Popup):
    pass


class MyStuff(BoxLayout):

    # num1 = StringProperty()
    # num2 = StringProperty()
    answer = ''

    def openPopup(self):
        the_popup = CustomPopup()
        the_popup.open()

    def addNum(self, *args):
        # self.answer = str(int(self.num1) + int(self.num2))
        self.answer = str(int(args[0]) + int(args[1]))
        print(self.answer)


class MyStuffApp(App):

    def build(self):
        return MyStuff()


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

【讨论】:

所以我使用了 app.root.addNum(number1, number2) 以及其他一些更改,这很有效。更改是... 在 py 文件中: answer = StringProperty() def addNum(self, num1, num2): self.answer = str(int(num1) + int(num2)) 在 CustomPopup 的 kv 文件中: 按钮: 文本: '添加' on_press: app.root.addNum(number1.text, number2.text) root.dismiss()【参考方案2】:

如果您在某处对该类有引用,则可以从 MyStuff 访问方法。 当您执行 root.addNum() 时,您会尝试访问 CustomPopup 中的一个方法,在这种情况下它是 root。 所以在这种情况下我要做的是将MyStuff 定义为App 类的一个属性(self.ms = MyStuff())。这样您就可以通过 app.ms.addNum()kv 中访问它 您还需要将数字传递给addNum

在py中:

class MyStuff(BoxLayout):

    answer = ''

    def openPopup(self):
        the_popup = CustomPopup()
        the_popup.open()

    def addNum(self, num1, num2):
        self.answer = str(int(num1) + int(num2))

class MyStuffApp(App):

    def build(self):
        self.ms = MyStuff()
        return self.ms

在 kv 中:

    Button:
        text: 'Add'
        on_press: app.ms.addNum(number1.text, number2.text)

【讨论】:

以上是关于Kivy Popup 无法访问 root 方法的主要内容,如果未能解决你的问题,请参考以下文章

Python Kivy 无法从另一个类访问 id

在未调用 Popup.open() 的方法中触发 Popup.dismiss() (kivy)

引用 Kivy 中动态创建的小部件的 id

Kivy 更新动态标签文本

如何用绝对坐标定位 Kivy Popup?

在 Kivy 中,为啥 popup.dismiss() 不从内存中删除弹出窗口?