Kivy 更改标签小部件来自另一个类的文本

Posted

技术标签:

【中文标题】Kivy 更改标签小部件来自另一个类的文本【英文标题】:Kivy Change Label widget Text from another class 【发布时间】:2018-09-05 10:24:09 【问题描述】:

我在从另一个类更新 kivy 标签文本运行时时遇到了一点麻烦。 我已经尝试了类似问题的所有可能解决方案,但无法得到结果。 在我的应用程序中,我有一个主类和另一个弹出类。我想从弹出类更新主类小部件的文本标签。

main.kv 文件

<JKmain>:
    the_time: _id_lbl_time
    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'top'
        BoxLayout:

            orientation: 'vertical'
            id: _tool_box
            size_hint: None,0.75
            width: 300

            Label:
                id: _id_lbl_time
                text: "Total Layers : "

    AnchorLayout:
        anchor_x: 'right'
        anchor_y: 'top'
        GridLayout:
            rows:2
            ...
            ...
            BoxLayout:
                orientation: 'horizontal'                           
                Button: 
                    on_release: app.root.current = "main"
                    text: "SELECT"
                    size_hint: 1,0.2
                    background_color: (1.0, 1.0, 0.0, 1.0)
                    on_release: root.popup_func(self)
                Button: 
                    text: "START"
                    size_hint: 1,0.2
                    background_color: (1.0, 0.0, 1.0, 1.0)
                    on_release: root.change_text(100)
                Button: 
                    text: "EXIT"
                    size_hint: 1,0.2
                    background_color: (1.0, 0.0, 1.0, 1.0)
                    on_release: root.exit_app(self)
<ConfirmPopup>:
    BoxLayout:
        orientation: 'vertical'
        FileChooserIconView:
            id: filechooser
            filters: ['*.zip']

        GridLayout:
            cols: 2 
            size_hint: 1,0.2
            Button:
                text: 'OK'
                on_release: root.dispatch('on_answer',filechooser.selection)
                size_hint: 1,0.2
            Button:
                text: 'Cancel'
                on_release: root.dispatch('on_answer', 'Cancel')
                size_hint: 1,0.2

ConfirmPopup 类:

class ConfirmPopup(BoxLayout):

    def __init__(self,**kwargs):
        self.register_event_type('on_answer')
        super(ConfirmPopup,self).__init__(**kwargs)
        ...
        ...
        self.total_images=0

    def on_answer(self, filename): 
        ...
        ...
        ...
        if not isdir_empty == "":
            folders = ([name for name in os.listdir(self.project_path)])
            targets = []
            for i in folders:
                if i.endswith('.png'):
                    targets.append(i)
                    self.total_images = len(targets)
        jk = JKMain()
        jk.change_text(self.total_images)

主类:

class JKMain(AnchorLayout):
    def __init__(self, **kwargs):
        super(JKMain, self).__init__(**kwargs)

    def change_text(self,layers):
        self.the_time.text = "Total Layers : " + str(layers)
        print "Total Layers = " + str(layers)

    def popup_func(self, instance):

        content = ConfirmPopup()
        content.bind(on_answer=self._on_answer)
        self.popup = Popup(title="Select .zip file",
                            content=content,
                            size_hint=(None, None),
                            size=(500,500),
                            auto_dismiss= False)
        self.popup.open()
    def _on_answer(self, instance, answer):
        self.popup.dismiss()

我可以使用 change_text 函数更新文本。从 ConfirmPopup 类中,我正在创建 JKMain 的实例并访问 change_text 函数来更改标签,但它不起作用

【问题讨论】:

您的jk = JKMain() 正在创建您的主类的新实例。如果您的应用创建了JKMain 的初始实例,那么您在尝试调用change_text() 方法时需要引用该初始实例。 【参考方案1】:

问题

它不起作用,因为通过创建另一个 JKMain 实例,现在您有两个 JKMain 实例,而您没有访问第一个实例,即根实例。

解决方案

作为解决方案工作的演示,在调用方法 之前,方法 on_answer 中的 self.total_images 设置为 8更改文本

kv 文件

    调用root.popup_func时无需传递self。 将根实例传递给方法on_answer。有关详细信息,请参阅示例和输出。

Python 脚本

    向方法on_answer添加一个新参数JKMain。 将新参数 obj 添加到方法 _on_answer

片段

main.kv

<JKmain>:
...
                    on_release: root.popup_func()
...
<ConfirmPopup>:
...
                on_release: root.dispatch('on_answer', filechooser.selection, app.root)

main.py

class ConfirmPopup(BoxLayout):

    ...
    def on_answer(self, filename, JKMain):
        self.total_images = 8
        print("JKMain=", JKMain)
        JKMain.change_text(self.total_images)

class JKMain(AnchorLayout):
    ...
    def popup_func(self):
        ...

    def _on_answer(self, instance, answer, obj):
        self.popup.dismiss()

示例

main.py

​​>
from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup


class ConfirmPopup(BoxLayout):

    def __init__(self, **kwargs):
        self.register_event_type('on_answer')
        super(ConfirmPopup, self).__init__(**kwargs)
        self.total_images = 0

    def on_answer(self, filename, JKMain):
        self.total_images = 8
        print("JKMain=", JKMain)
        JKMain.change_text(self.total_images)


class JKMain(AnchorLayout):
    def __init__(self, **kwargs):
        super(JKMain, self).__init__(**kwargs)

    def change_text(self, layers):
        self.the_time.text = "Total Layers : " + str(layers)
        print("Total Layers = " + str(layers))

    def popup_func(self):

        content = ConfirmPopup()
        content.bind(on_answer=self._on_answer)
        self.popup = Popup(title="Select .zip file",
                           content=content,
                           size_hint=(None, None),
                           size=(500, 500),
                           auto_dismiss=False)
        self.popup.open()

    def _on_answer(self, instance, answer, obj):
        self.popup.dismiss()


class Main(App):

    def build(self):
        return JKMain()


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

main.kv

#: kivy 1.10.0

<JKmain>:
    the_time: _id_lbl_time
    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'top'
        BoxLayout:

            orientation: 'vertical'
            id: _tool_box
            size_hint: None,0.75
            width: 300

            Label:
                id: _id_lbl_time
                text: "Total Layers : "

    AnchorLayout:
        anchor_x: 'right'
        anchor_y: 'top'
        GridLayout:
            rows:2
            BoxLayout:
                orientation: 'horizontal'
                Button:
                    on_release: app.root.current = "main"
                    text: "SELECT"
                    size_hint: 1,0.2
                    background_color: (1.0, 1.0, 0.0, 1.0)
                    on_release: root.popup_func()
                Button:
                    text: "START"
                    size_hint: 1,0.2
                    background_color: (1.0, 0.0, 1.0, 1.0)
                    on_release: root.change_text(100)
                Button:
                    text: "EXIT"
                    size_hint: 1,0.2
                    background_color: (1.0, 0.0, 1.0, 1.0)
                    on_release: root.exit_app(self)

<ConfirmPopup>:
    BoxLayout:
        orientation: 'vertical'
        FileChooserIconView:
            id: filechooser
            filters: ['*.zip']

        GridLayout:
            cols: 2
            size_hint: 1,0.2
            Button:
                text: 'OK'
                on_release: root.dispatch('on_answer', filechooser.selection, app.root)
                size_hint: 1,0.2
            Button:
                text: 'Cancel'
                on_release: root.dispatch('on_answer', 'Cancel')
                size_hint: 1,0.2

输出

【讨论】:

再次感谢您:-)。

以上是关于Kivy 更改标签小部件来自另一个类的文本的主要内容,如果未能解决你的问题,请参考以下文章

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

更新另一个类中的 kivy 标签文本

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

滚动小部件中的 Kivy 标签文本换行

如何在 kivy python 中的标签、文本输入和其他小部件中添加标题

在 Kivy 中传递自定义小部件属性