在kivy中通过id获取子项并为其添加新标签

时间:2015-04-20 04:45:33

标签: python kivy

我是python和kivy的新手。我最近正在开发一个基于此站点代码的kivy服务器/客户端应用程序:http://kivy.org/docs/guide/other-frameworks.html

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

然而,由于我对kivy和python的知识有限,而不是添加新的小部件,我只能实现更新一个小部件。我只是试图使用for循环添加新的小部件,不幸的是我被卡住了

以下是它正在运行的版本,因为它只更新标签

类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

这是因为它试图添加新的子窗口小部件而无法正常工作的版本

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)消息后添加带有各种标签的多个分散小部件?

非常感谢

1 个答案:

答案 0 :(得分:1)

要按ID访问小部件(如果您在kv语言代码中使用ID,则提供),请使用 ID ,如下所示:

...
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

的更多信息

希望这有帮助。