【问题标题】:Kivy update label dynamically on canvasKivy 在画布上动态更新标签
【发布时间】:2019-11-14 14:49:12
【问题描述】:

我正在尝试更新画布上的标签,但只有当我从 MyApp(APP) 调用 update() 方法时它才会更改。

有趣的是,obj Slider (on touch) 方法可以完美运行

 from kivy.app import App
 from kivy.uix.widget import Widget
 from kivy.core.window import Window
 from kivy.uix.label import Label
 from kivy.uix.floatlayout import FloatLayout
 from kivy.uix.gridlayout import GridLayout
 from kivy.uix.boxlayout import BoxLayout
 from kivy.graphics import (Color, Ellipse)
 from kivy.uix.slider import Slider
 import random
 from functools import partial

 class Canvas_w(Widget):
    def __init__(self, **kwargs):
        self.i = 0
        super(Canvas_w, self).__init__(**kwargs)
        self.label_text =Label(text= "0",color = (255,0,0))

    def update_text(self, text):
        self.label_text.text = text

    def on_touch_down(self, touch):
        with self.canvas:
            d=30
            self.i+=1
            Color(1., 0, 0)
            Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(20,20))
            self.label_text=str(self.i)

class Label_l(GridLayout):
     bones = 0
     def __init__(self, **kwargs):
         super(Label_l, self).__init__(**kwargs)
         self.label_text =Label(text= "0")
         self.add_widget(self.label_text)
         #self.label_text.text=self.C.i
     def update_text(self, text):
         Label_l.bones=text
         self.label_text.text = str(Label_l().bones)#
         Label_l.text=str(Label_l().bones)

class WidgetContainer(GridLayout):
    sld_value = 0.00001
    def __init__(self, **kwargs):
         super(WidgetContainer, self).__init__(**kwargs)
         self.cols = 1
         self.speedControl = Slider(min=0.00001, max=3, step=0.0001)
         self.add_widget(Label(text="Speed Iteration"))
         self.add_widget(self.speedControl)
         self.add_widget(Label(text=''))
         self.speedValue = Label(text="0.00001")
         self.add_widget(self.speedValue)
         self.speedControl.bind(value=self.on_value)
    def on_value(self, instance, speed):
         self.sld_value = speed
         WidgetContainer.sld_value = self.sld_value

         self.speedValue.text = str(round(speed,5))
class MyApp(App):
    def build(self):
         b3 = BoxLayout(orientation="horizontal")
         b1 = FloatLayout()
         self.painter = Canvas_w()
         self.label_l= Label_l()
         b1.add_widget(self.label_l)
         b1.add_widget(self.painter)
         b1.add_widget(WidgetContainer())
         b3.add_widget(b1)
         return(b3)
if __name__=="__main__":
     MyApp().run()

我正在尝试更新画布上的标签,但只有当我从 MyApp(APP) 调用 update() 方法时它才会更改。

有趣的是,obj Slider (on touch) 方法可以完美运行

【问题讨论】:

    标签: python label kivy


    【解决方案1】:

    您的代码存在一些问题:

    • Labelcolor 属性需要一个包含四个值的列表,每个值都在 0 到 1 的范围内。在 Canvas_w 类中将 self.label_text =Label(text= "0",color = (255,0,0)) 更改为 self.label_text =Label(text= "0",color = (1,0,0,1))
    • 上面的Label 永远不会被绘制。需要在Canvas_w__init__()方法中添加self.add_widget(self.label_text)
    • Label_l 类中还有另一个 Label,它被绘制在 Canvas_w 中的 Label 之上。

    解决上述问题后,我相信你的代码会如你所愿的工作。

    如果您调用self.canvas.clear(),看起来好像Canvas_wlabel_text 子级已被删除。实际上它并没有被删除,只是不可见(可能是透支)。使其可见的一种方法是通过删除它然后重新添加它来确保最后绘制它(最后添加的子元素最后绘制),如下所示:

            self.canvas.clear()
            self.remove_widget(self.label_text)
            self.add_widget(self.label_text)
    

    经过更多研究,我相信canvas.clear() 正在从Canvas 中删除Label 的绘图。但是,您可以使用以下命令在 canvas.before 上进行绘图:

    with self.canvas.before:
    

    on_touch_down() 方法中。而不是使用:

    self.canvas.clear()
    

    使用:

    self.canvas.before.clear()
    

    相信你的Label做完以上操作后会正确显示的。

    【讨论】:

    • 约翰·安德森,你救了我的命!非常感谢!颜色和 self.add_widget(self.label_text) 工作,但在 super 之后应该放!
    • 但是有问题,当我清除画布(canvas.clear())时,这个标签消失了!可能你知道如何再次加载标签吗?
    • 这很奇怪,我并没有声称理解为什么会发生这种情况,但我在上面的回答中添加了一种解决方法。
    • 我添加了使用canvas.before的建议。
    猜你喜欢
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 2023-03-19
    • 2015-06-09
    • 1970-01-01
    • 2021-12-15
    相关资源
    最近更新 更多