更改 Kivy 中的弹出文本

Posted

技术标签:

【中文标题】更改 Kivy 中的弹出文本【英文标题】:Change popup text in Kivy 【发布时间】:2018-10-30 16:04:57 【问题描述】:

我是 Kivy 的新手,所以这可能是一个微不足道的问题。我正在开发一个有两个屏幕的项目,每个屏幕都包含一个生成弹出窗口的按钮。我希望弹出窗口显示一个包含当前屏幕名称的语句。我的问题是尽管有一种方法可以更改弹出文本,但始终显示占位符文本。为什么changeText方法不改变弹窗的文字?

我的问题似乎与显示的类似:

Kivy Label.text Property doesn't update on the UI

但是,我在理解如何将其应用于我的具体情况时遇到了一些麻烦。

Python 代码:

class Screen1(Screen):  
    pass

class Screen2(Screen):
    pass 

class MyManager(ScreenManager):
    pass

class PopUp(Popup):
    def changeText(self,nameStr):
        self.ids.label.text = "You are on Screen %s!" %nameStr #this is text that I want to display 

class PrimaryApp(App):
    def build(self):
        return MyManager()

PrimaryApp().run()

Kv 代码:

#:import Factory kivy.factory.Factory
<MyManager>:
    Screen1:
        id: screen1
    Screen2: 
        id: screen2

<Screen1>:
    name: "one"
    GridLayout:
        id: grid
        rows: 2
        Button:
            id: button1
            text: "Go to Screen Two"
            on_release: root.manager.current = "two" 
        Button: 
            id: button2
            text: "Display Popup" 
            on_release: 
                Factory.PopUp().changeText(root.name)
                Factory.PopUp().open()
<Screen2>: 
    name: "two" 
    GridLayout:
        id: grid
        rows: 2 
        Button:
            id: button1
            text: "Go to Screen One" 
            on_release: root.manager.current = "one" 
        Button: 
            id: button2
            text: "Display Popup"
            on_release:
                Factory.PopUp().changeText(root.name)
                Factory.PopUp().open()


<PopUp>:
    id:pop
    size_hint: (.5,.5)
    title: "Notice!" 
    Label: 
        id: label
        text: "PLACEHOLDER TEXT" #this is not the code I want displayed

[1]:

【问题讨论】:

【参考方案1】:

使用 Popup 事件,on_open 来更改 Popup 内容,Label 小部件的文本。

Popup » API

事件:on_open: 被解雇 当弹出窗口打开时。

片段

<PopUp>:
    on_open:
        label.text = "You are on Screen %s!" % app.root.current
    id:pop
    ...

示例

main.py

​​>
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup


class Screen1(Screen):
    pass


class Screen2(Screen):
    pass


class MyManager(ScreenManager):
    pass


class PopUp(Popup):
    pass


class PrimaryApp(App):
    def build(self):
        return MyManager()


PrimaryApp().run()

primary.kv

#:kivy 1.10.0
#:import Factory kivy.factory.Factory

<MyManager>:
    Screen1:
        id: screen1
    Screen2:
        id: screen2

<Screen1>:
    name: "one"
    GridLayout:
        id: grid
        rows: 2
        Button:
            id: button1
            text: "Go to Screen Two"
            on_release: root.manager.current = "two"
        Button:
            id: button2
            text: "Display Popup"
            on_release:
                Factory.PopUp().open()
<Screen2>:
    name: "two"
    GridLayout:
        id: grid
        rows: 2
        Button:
            id: button1
            text: "Go to Screen One"
            on_release: root.manager.current = "one"
        Button:
            id: button2
            text: "Display Popup"
            on_release:
                Factory.PopUp().open()


<PopUp>:
    on_open:
        label.text = "You are on Screen %s!" % app.root.current
    id:pop
    size_hint: (.5,.5)
    title: "Notice!"
    Label:
        id: label
        text: "PLACEHOLDER TEXT" #this is not the code I want displayed

输出

【讨论】:

【参考方案2】:

每次调用Factory().Popup() 时,它都会创建一个全新的Popup,与之前的无关。你能做的是:

在kv中:

...
<Screen1>:
    name: "one"
    GridLayout:
        id: grid
        rows: 2
        Button:
            id: button1
            text: "Go to Screen Two"
            on_release: root.manager.current = "two"
        Button:
            id: button2
            text: "Display Popup"
            on_release:
                p = Factory.PopUp()
                p.changeText(root.name)
                p.open()

第二个屏幕也是如此。但是每次您释放这些按钮时,它都会创建一个新创建的弹出窗口,浪费了太多内存。您可以做的最好的事情是使用弹出窗口初始化您的屏幕管理器,然后只更改此弹出窗口的文本:

Python:

...
from kivy.properties import ObjectProperty

...
class PopUp(Popup):
    def changeText(self,*args):
        self.ids.label.text = "You are on Screen %s!" % args[0].current

class MyManager(ScreenManager):
    popup = ObjectProperty()

    def __init__(self, **kwargs):
        super(MyManager, self).__init__(**kwargs)
        self.popup = PopUp()
        self.bind(current=self.popup.changeText)

和kv:

...
<PopUp>:
    id:pop
    size_hint: (.5,.5)
    title: "Notice!"
    Label:
        id: label
        text: "You are on Screen one!"

<Screen1>:
    name: "one"
    GridLayout:
        id: grid
        rows: 2
        Button:
            id: button1
            text: "Go to Screen Two"
            on_release: root.manager.current = "two"
        Button:
            id: button2
            text: "Display Popup"
            on_release:
                root.manager.popup.open() #Same thing for the second screen

【讨论】:

我有几个后续问题: 1) args[0].current 的作用是什么? 2) self.bind(current=self.popup.changeText)的作用是什么? args[0] 是您的屏幕管理器,因此 args[0].current 是当前屏幕的名称。绑定函数将 changeText 方法“绑定”到屏幕管理器当前属性,因此每次当前屏幕更改时,都会自动调用 changeText

以上是关于更改 Kivy 中的弹出文本的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 jQuery DatePicker 控件的弹出位置

Kivy:访问不同类的方法

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

自动关闭kivy中的弹出窗口

python中的Kivy弹出窗口,按钮上有多个on_release操作

更改从 Swift 中的故事板创建的弹出框的箭头颜色