将函数变量传递给标签

Posted

技术标签:

【中文标题】将函数变量传递给标签【英文标题】:Pass function variable to label 【发布时间】:2017-07-08 21:03:46 【问题描述】:

我在 Kivy 框架上苦苦挣扎了一段时间。我在网上找不到我的问题的答案。

我有两个文件:main.py 和 .kv 文件。 在 main.py 文件中,我在 Boxlayout 中有函数。

例如:

class Box(BoxLayout):

    def change(self):
            variable = 0

            while variable < 10:
                text = "Some text " + str(variable)
                variable += 1

如你所见,有一个字符串变量“text”,这个变量在每个循环中都不一样。

现在在 .kv 文件中我有一个标签。 例如:

Box:
    BoxLayout:
        Button:
            id: butt
            text: ""
            on_press: root.change()
        Label:
            id: label_text

我希望按钮运行函数 change(),并且希望看到标签中显示的“文本”变量的值。 所以用户点击按钮后,他会看到标签上的文字发生变化: “一些文本 0”、“一些文本 1”、“一些文本 2”....“一些文本 9”。

我曾尝试在 main.py 文件中使用标签 ID,例如:

(内部变化函数)

label = self.ids['label_text']
self.count = str(variable)
label.text = "Some text " + self.count

但最终一无所获。 我想我可以在函数末尾使用“返回文本”来做到这一点,但我不想只传递循环中的最后一个“文本”变量。我希望标签在循环期间变量更改时更改文本。

请指教!

【问题讨论】:

【参考方案1】:

from kivy.properties import StringProperty 并将您的标签文本定义为label_text = StringProperty(),这样当您的逻辑发生更改时,它将在 GUI 中更新。 在您的.kv 文件中将text: root.label_text 添加到Label 属性和您的.py 文件中:

class Box(BoxLayout):
    label_text = StringProperty()

    def change(self):
            variable = 0
            while variable < 10:
                self.label_text = "Some text " + str(variable)
                variable += 1

这是关于在 GUI 中更新标签文本值的问题的答案。但不要使用while True 之类的循环或您在代码中使用的循环,因为它会阻止kivy 的GUI 线程自我更新。而是使用 kivy Clock (from kivy.clock import Clock) 来安排任务并以特定的时间间隔运行它,这样 GUI 线程就不会被阻塞。类似的东西

class Box(BoxLayout):

    label_text = StringProperty()
    interval = 0.5  # Second
    offset = 0

    def change(self):
        # You ask the clock to update the label's value every self.interval (0.5) second
        self.event = Clock.schedule_interval(self.update_label_text, self.interval)

    def update_label_text(self, dt):
        if self.offset < 10:
            self.label_text = "some_text" + str(self.offset)
            self.offset += 1
        else:
            # Finally ask the clock to forget about updating
            Clock.unschedule(self.event)

【讨论】:

谢谢。这解决了我的问题,但是……我仍然不是 100% 清楚这到底是如何工作的。你能推荐一些好的kivy教程吗? @Maciejjy 如果它有效,接受并投票回答会很好:) 你拿了这个吗? kivy.org/docs/tutorials/pong.html 当然。但我不能投票。收到一些消息,对于代表少于 15 的用户,不要更改帖子分数。 没关系。教程呢?你拿了吗? 只是检查一下。看起来不错,它涵盖了我需要的东西。谢谢!【参考方案2】:

在标签中显示文本仍然存在一些问题。使用简短的功能,一切似乎都很好,但我有很多打开文件、ifs 和写入数据库的功能:

def add_to_base(self, dt):
    self.adding = "Adding to database..."
    with open("new_links.txt", "r", encoding='utf-8') as f:
        for line in f:
            working on html here
            xxx = got list of string here
            for x in xxx:
                if ....
                    zzz = got another list with string
            for i in xxx:
                if
                 .
                 .
                Lots of elif's
            write element to database
            print("Added to databes")
            if element is last element:
                Clock.unschedule(self.event)

当然,这不是实际代码,只是对它的工作方式进行建模。 我想从此函数显示和更新“self.adding”文本。 在 .kv 文件中,我有带有文本的标签:self.adding 属性。 在运行这个 add_to_base 函数时:

def update_base(self):
    self.event = Clock.schedule_interval(self.add_to_base, self.interval)

问题是,文本显示在标签上,但在此函数的最后。此函数需要很长时间才能完成(大约需要 15 分钟来处理元素并将它们添加到数据库中),并且当函数完成时,会显示文本。我想在一开始就显示这个文本。

【讨论】:

函数add_to_base() 会阻塞kivy GUI 线程,直到它完成。正如我所说,避免使用 forwhile 运行此类循环,并使用 kivy Clock 为您安排它们。我建议将文件的所有行添加到Queue(),然后安排一个间隔从Queue() 读取并对其进行操作,而不是您所做的阻止GUI 线程的那个。阅读关于 python Queue() 哦,好的。所以如果我们有很长的函数要结束(比如 15 分钟),那么 kivy.Clock 不能比每 15 分钟更快地刷新这个函数的任何变量?在这种情况下,间隔并不重要,因为它小于函数时间? 不知何故,我的意思是把任务分解成更小的任务,然后让时钟每隔一段时间完成每个任务。

以上是关于将函数变量传递给标签的主要内容,如果未能解决你的问题,请参考以下文章

将类型变量传递给函数

将变量传递给函数\使用该变量返回一个新值\重复直到值达到 0

如何将两个变量传递给 python 函数并返回两个变量? [复制]

将变量传递给 .animate() 函数 JQuery

承诺,如何将变量传递给 .then 函数

将变量的全部内容传递给函数