通过 kivy 中的 id 获取 child 并为其添加新标签

get child by id in kivy and add new label to it

我对 python 和 kivy 还很陌生。我最近正在开发一个基于此站点代码的 kivy server/client 应用程序:http://kivy.org/docs/guide/other-frameworks.html

我的目标是创建一个服务器应用程序,它可以从客户端应用程序接收消息,然后将来自客户端应用程序的一条消息转换为一个标签,该标签可以单独 touched/moved/scaled 在分散小部件中。 (即,如果您从客户端应用程序发送了 10 条不同的消息,您应该能够在服务器屏幕上看到 10 个您可以操作的标签)

但是由于我对kivy和python的了解有限,我没有添加新的widgets,只能实现更新一个widget。我刚刚尝试使用 for 循环添加新的小部件,不幸的是我卡住了

这是它工作的版本,因为它只更新标签

class ServerApp(App):

def build(self):
    self.layout = BoxLayout(orientation='vertical', spacing=10)

    self.label = Button(text='Censoring process begin\nBeware of keyword "umbrella"\n ', color=[1.0,1.0,1.0,1.0])
    self.label.color = [0.9,0.2,0.2,1.0]

    self.upperscroll = Button(pos_hint={'x': 0, 'center_y': .5}, size_hint=(None, None))

    self.scatter = Scatter()

    self.displaybox = Label()
    self.displaybox.color = [0.4,0.9,0.4,1.0]

    reactor.listenTCP(8800, EchoFactory(self))
    reactor.listenTCP(8880, MultiEchoFactory(self))

    self.layout.add_widget(self.label)
    self.layout.add_widget(self.scatter)

    self.scatter.add_widget(self.displaybox)

    return self.layout

def handle_message(self, msg):

   if any(word in msg.lower() for word in wordlist):

       self.displaybox.color = [0.9,0.4,0.4,1.0]
       self.displaybox.text = "content blocked"
       self.label.text += "Alert! Sender posts %s \n" %msg


   else:
       self.label.text += "Safe - sender posts %s \n" %msg
       self.displaybox.color = [0.4,0.9,0.4,1.0]
       self.displaybox.text = "%s" % msg



   msg = msg


   return msg

这个版本无法正常工作,因为它正在尝试添加新的 child 小部件

class ServerApp(App):


def build(self):
    i = 0
    self.layout = BoxLayout(orientation='vertical', spacing=10)

    self.label = Button(text='Censoring process begin\nBeware of keyword "umbrella"\n ', color=[1.0,1.0,1.0,1.0])
    self.label.color = [0.9,0.2,0.2,1.0]

    self.upperscroll = Button(pos_hint={'x': 0, 'center_y': .5}, size_hint=(None, None))

    self.scatter = Scatter(id="scatter" + str(i))

    self.displaybox = Label(id='displaybox' + str(i))
    self.displaybox.color = [0.4,0.9,0.4,1.0]

    reactor.listenTCP(8800, EchoFactory(self))
    reactor.listenTCP(8880, MultiEchoFactory(self))

    self.layout.add_widget(self.label)
    self.layout.add_widget(self.scatter)

    self.scatter.add_widget(self.displaybox)

    return self.layout

def handle_message(self, msg):

    for i in range(100):
       if any(word in msg.lower() for word in wordlist):

          self.layout.add_widget(self.scatter+str(i)(pos=(random(350),random(400))))
          self.scatter+str(i).add_widget(self.displaybox+str(i))

          **self.displaybox+i**.color = [0.9,0.4,0.4,1.0]
          **self.displaybox+i**.text = "content blocked"
            # this is where error occurs as python cannot identify the new label by adding "i"
          self.label.text += "Alert! Sender posts %s \n" %msg


    else:
         self.label.text += "Safe - sender posts %s \n" %msg
         self.scatter+i.add_widget(self.displaybox+i)
         self.displaybox+i.color = [0.4,0.9,0.4,1.0]
         self.displaybox+i.text = "%s" % msg

    i+=1

    msg = msg


    return msg

我想知道一旦从客户端应用程序发送了 (msg) 消息,我该如何解决这个问题并添加多个带有各种标签的分散小部件?

非常感谢

要通过 id 访问小部件(前提是您在 kv 语言代码中使用 id),请使用 ids,如下所示:

...
scatter_id = 'scatter' + str(i) # form the id by string
scatter_widget = getattr(self.ids, scatter_id) # use getattr to access it 
displaybox_id = 'displaybox' + str(i)
displaybox_widget = getattr(self.ids, displaybox_id)
scatter_widget.add_widget(displaybox_widget)
...

或者:

self.ids['scatter' + str(i)].add_widget(self.ids['displaybox' + str(i)])
...

以上基本相同,更多的是可读性和编码风格。

您可以阅读更多关于 Widget.ids here

希望对您有所帮助。