【问题标题】:Kivy text markup printing its own syntaxKivy 文本标记打印自己的语法
【发布时间】:2016-04-21 14:18:24
【问题描述】:

我正在测试 Kivy 的标记功能。我的测试程序的基本轮廓是有 4 个标签和一个按钮,如果按下按钮,它会改变标签文本第一个字母的颜色。现在,问题是当我第一次按下按钮时,它会改变所有标签文本的第一个字母的颜色,但是从第二次按下开始,它开始以相反的方式在文本的开头添加标记语法.这是程序:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.lang import Builder
import string

Builder.load_string(
'''
<CLabel@Label>:
    markup: True

<box>:
    orientation: 'vertical'

    Button:
        text: 'press'
        on_press: app.change()


    CLabel:
        id: a
        text: 'abcd'

    CLabel:
        id: b
        text: 'efgh'

    CLabel:
        id: c
        text: 'ijkl'

    CLabel:
        id: d
        text: 'mnop'
'''
)

class box(BoxLayout):
    pass

class main(App):
    def change(self):
        for lol in string.lowercase[:4]:
            self.root.ids[lol].text = '[color=#E5D209]{}[/color]{}'.format(self.root.ids[lol].text[0], self.root.ids[lol].text[1:])

    def build(self):
        return box()

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

这是第一次按下后的输出:

这是第二次按下后的输出:

这是第三次按下后的输出:

希望您现在就解决问题。文本开头的标记语法随着按钮被按下的次数而不断增加。

我认为这可能是循环的错。所以我删除了循环并仅使用第一个小部件进行了测试。同样的问题。

现在,当我通过像这样更改更改函数的内容来更改颜色时,这是一个问题:

def change(self):
    self.root.ids.a.text = '[color=#E5D209]a[/color]bcd'
    self.root.ids.b.text = '[color=#E5D209]e[/color]fgh'
    self.root.ids.c.text = '[color=#E5D209]i[/color]jkl'
    self.root.ids.d.text = '[color=#E5D209]m[/color]nop'

它工作得很好。但是通过这种方法,我将不得不复制粘贴很多行。这只是我正在做的事情的一个sn-p。我正在处理的实际项目有超过 15 个标签,并且为每个标签复制粘贴很烦人。如果用循环来完成会好很多。它使工作变得简短而精确。

在此之后,出于沮丧,我尝试通过以下代码使用 get_color_from_hex 方法:

self.root.ids[lol].text[0] = self.root.ids[lol].text[0].get_color_from_hex('#E5D209')

但我最终收到一条错误消息:

AttributeError: 'str' object has no attribute 'color'

如果有人能改变上帝知道有多少标签的文本的第一个字母的颜色,我会非常高兴。 :'(

【问题讨论】:

    标签: python kivy kivy-language


    【解决方案1】:

    标记是存储在text 中的字符串的一部分。所以第二次运行循环时,确实第一个字符 ([) 被插入到标记标签之间,从而弄乱了解析。

    您想要做的可以通过将原始文本存储在另一个StringProperty 中来实现,我们称之为_hidden_text。然后,在循环中,你可以设置

    self.root.ids[lol].text = '[color=#E5D209]{}[/color]{}'.format(self.root.ids[lol]._hidden_text[0], self.root.ids[lol]._hidden_text[1:])
    

    这样可以避免重复使用添加的标记。 当然,您可能希望设置绑定以使分配 _hidden_text→text 自动。

    编辑:

    添加此类定义:

    class CLabel(Label):
        hidden_text = StringProperty('')
    

    然后将CLabel的kv样式改为

    <CLabel>:
        markup: True
        text: self.hidden_text
    

    CLabel 的每次使用都应该是这样的

    CLabel:
        id: a
        hidden_text: 'abcd'
    

    【讨论】:

    • 我不想这么说,但我没有太多使用属性的经验。而且当我使用属性时,我遇到的问题远远超出了我的理解。 :\ 但是我在不使用 StringProperty 的情况下为我的程序找到了一种解决方法。在这里,看看:pastebin.com/25KmXnMu 现在,问题是我必须输入两次文本。 :\ 在标签下,当我尝试hidden_text: self.text 时,我遇到了和以前一样的问题。即使我在 for 循环下将 hidden_text 分配给 self.root.ids[lol].text,我也遇到了同样的问题。
    • 我尝试在这里使用 StringProperty pastebin.com/2ay2KvP3。这是使用 StringProperty 的方式吗?输出仍然存在问题中提到的问题。
    • @ParthibBis 添加了如何使用StringProperty 的示例(它应该是CLabel 类的属性),并展示了如何不必重复键入文本。顺便说一句,如果您需要 CLabel 类的行为类似于 Label(即文本应通过 text 设置),请查看 AliasProperty。
    • 成功了!我肯定会调查 AliasProperty。在这样做的同时,我也必须开始更多地练习其他属性。谢谢。
    猜你喜欢
    • 2021-07-17
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2021-09-29
    • 2023-03-09
    相关资源
    最近更新 更多