如何逐个字符显示标签文本?

Posted

技术标签:

【中文标题】如何逐个字符显示标签文本?【英文标题】:How do I display Label text character-by-character? 【发布时间】:2020-10-02 23:28:44 【问题描述】:

我一直在尝试在 Kivy 上编写一个基于文本的小型冒险游戏。这意味着,将有大量文本供用户阅读,如果不是一次显示 Label 中的所有文本,而是以简单的方式逐个字符显示,这会更容易阅读“动画”。在这个“动画”结束时,将显示整个文本。

在普通的 Python 中,我想要的应该是这样的:

text1 = "Now tell me, what is your astrological sign?\n"
    for character in text1:
        sys.stdout.write(character)
        sys.stdout.flush()
        time.sleep(0.05)

在 Kivy 中,这似乎要困难得多,因为 sleep 函数只是“休眠”整个应用程序。我四处寻找,并没有真正找到任何关于这个特定问题的东西。其他一些人通过使用 Kivy Clock 对象解决了他们对 time.sleep 的需求,但即使在这里我也只能让文本一次显示一个字符(参见下面的代码),这绝对不是我想要的时间>。我希望所有字符加起来,并在这个“动画”结束时让整个标签文本站在那里。

from kivy.app import App
from kivy.lang import Builder
from kivy.properties import StringProperty
import time
from kivy.clock import Clock

kv = '''

BoxLayout:
    orientation: 'vertical'
    Label:
        text: app.text
    Button:
        text: 'click me'
        on_press: app.clicked()

'''


class MyApp(App):
    text = StringProperty("hello world")
    lst = [1,2,3,4,5,6,7,8,9,10]

    def build(self):
        return Builder.load_string(kv)

    def clicked(self):
        Clock.schedule_interval(self.clicked2, 0.5)

    def clicked2(self, count):
        if len(self.lst) == 0:
            return False
        self.text = "clicked!" + str(self.lst[len(self.lst)-1])
        self.lst.pop()


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

这是我目前能想到的最好的,但同样,这甚至不是我真正想要的。

有没有人有更多经验可以帮助我解决这个问题?将不胜感激,谢谢!

【问题讨论】:

【参考方案1】:

我已经认识你了,回答你的问题。但是,我将使用scope variable 向您展示更短的代码。要使用它声明nonlocal [var]

例子:

def A(i=0):
  def c():
    nonlocal i; i += 1
  print(i)        #0
  c(); print(i) #1
  c(); print(i) #2
  c(); print(i) #3
A()

我在下面的代码中使用like:

from kivy.lang import Builder
from kivy.properties import StringProperty
import time
from kivy.clock import Clock
from kivy.app import App

kv = '''

BoxLayout:
    orientation: 'vertical'
    Label:
        text: app.text
        text_size: self.size
        valign: "middle"
        padding: root.width/20, root.height/20
    Button:
        text: 'click me'
        on_press: app.clicked()

'''


class MyApp(App):
    text = StringProperty("hello world")
    blabla = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum"
    def build(self): return Builder.load_string(kv)

    def clicked(self, i=0):
      def clicked2():
        nonlocal i; i += 1
        if i > len(self.blabla): return False
        self.text = self.blabla[:i]
      Clock.schedule_interval(lambda count: clicked2(), 0.05)


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

【讨论】:

这真的很酷,感谢您的意见!我之前也尝试过使用全局变量,但直到现在我才听说过非局部变量。使用嵌套函数的好主意!另一个我没有想到的想法。谢谢你的帖子:)【参考方案2】:

我成功了!下面的代码正是我想要的。我只是使用字符串索引和列表来使用 Clock.schedule_interval() 函数对其进行迭代。

我在 kv 中添加了“valign”和一些填充以使其看起来更好。并且 text_size: self_sice 可以在文本分布在多行时使文本换行。

from kivy.lang import Builder
from kivy.properties import StringProperty
import time
from kivy.clock import Clock

kv = '''

BoxLayout:
    orientation: 'vertical'
    Label:
        text: app.text
        text_size: self.size
        valign: "middle"
        padding: root.width/20, root.height/20
    Button:
        text: 'click me'
        on_press: app.clicked()

'''


class MyApp(App):
    text = StringProperty("hello world")
    blabla = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum"
    lst = []
    for x in range(len(blabla)+1):
        print(x)
        lst.append(x)
    lst.reverse()

    def build(self):
        return Builder.load_string(kv)

    def clicked(self):
        Clock.schedule_interval(self.clicked2, 0.05)

    def clicked2(self,count):
        if len(self.lst) == 0:
            return False
        self.text = str(self.blabla[:self.lst[len(self.lst)-1]])

        self.lst.pop()


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

【讨论】:

以上是关于如何逐个字符显示标签文本?的主要内容,如果未能解决你的问题,请参考以下文章

如何在静态文本标签中包含特殊字符?

如何在目标c中的多个标签上显示文本文件中的随机单词

如何在 QLabel 中查看未知的 HTML 标签?

UILabel 垂直对齐缺少的空间

无法在标签或文本字段中显示字符串

如何根据结果更改文本标签颜色?