Dynamic add Label / Switch Objects into existing KV-Defined Layout

19 views
Skip to first unread message

henry herrgesell

unread,
Oct 21, 2017, 7:06:31 PM10/21/17
to Kivy users support
Hello,

I've defined my Layout by KV-File and wants to add a dynamic number of objects into a Specific Tree. Without adding by Python it already worked, but want to redesign my Project to be more dynamic:
The RED Objects should be added via Python instead of being predefined.


main.kv
<RootWidget>:
    width: 800.0
    height: 480.0
    TabbedPanel:
        width: 800.0
        height: 480.0
        do_default_tab: False
        TabbedPanelItem:
            text: 'Uebersicht'
            RelativeLayout:
                Label:
                    text: ""
                    pos: 100,240
                    font_size: 20
                    id: weatherTemp
                AsyncImage:
                    id: weatherImg
                    source: "loading.png"
                    pos: 280,240
                BoxLayout:
                    orientation: 'horizontal'
                    BoxLayout:
                        orientation: 'vertical'
                        BoxLayout:
                            Label:
                                text: "SW03"
                                font_size: 20
                            Switch:
                                on_active: app.setSwitch(*args)
                                id: switch03
                        BoxLayout:
                            Label:
                                text: "SW01"
                                font_size: 20
                            Switch:
                                on_active: app.setSwitch(*args)
                                id: switch01
                        BoxLayout:
                            Label:
                                text: "SW02"
                                font_size: 20
                            Switch:
                                on_active: app.setSwitch(*args)
                                id: switch02
                    BoxLayout:
                        orientation: 'vertical'
                        BoxLayout:
                            Label:
                                text: "Aussen Temperatur:"
                                font_size: 20
                            Label:
                                id: outTemp
                                text: app.outTemp
                                font_size: 20
                        BoxLayout:
                            Label:
                                text: "Innen Temperatur:"
                                font_size: 20
                            Label:
                                id: inTemp
                                text: app.inTemp
                                font_size: 20
                        BoxLayout:
                            Label:
                                text: "Test Temperatur:"
                                font_size: 20
                            Label:
                                text: app.testTemp
                                font_size: 20
        TabbedPanelItem:
            text: 'Licht'
            BoxLayout:
                ColorPicker:
                    id: colorPicker
                    on_color: app.colorChange('light1',*args)

Currently my Python Code is (only related snippets):
class RootWidget(FloatLayout):
    @mainthread
    def setState(self, eid, state):
        if(state == "off"): state = False
        elif(state == "on"): state = True
        self.ids[eid].active = state
    @mainthread
    def setWeatherImg(self, url):
        self.ids.weatherImg.source = url
    @mainthread
    def setWeatherTemp(self, temp):
        self.ids.weatherTemp.text = temp
class MainApp(App):
    tempSensors = {}
    deviceList = {}
    deviceListByName = {}
    tempSensors['feuchte01'] = StringProperty()
    tempSensors['tempout'] = StringProperty()
    tempSensors['tempartnet'] = StringProperty()
    inTemp = StringProperty()
    outTemp = StringProperty()
    testTemp = StringProperty()
    def build(self):
        self.rootWidget = RootWidget()
        self.pilight = PilightConnection()
        self.pilight.connect()
        self.loadPilightConfig()
        self.lastResponse = ""
        self.owm = pyowm.OWM(API_key='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', language='de')
        start_new_thread(self.listenToPilight, (self.pilight,self,))
        Clock.schedule_once(self.updateWeather, 0)
        Clock.schedule_interval(self.updateWeather, 60)
        self.dmx = ArtNet_Sender()
        self.dmx.add_artnet_node("192.1XX.XXX.XXX")
        return self.rootWidget
    def updateWeather(self, args):
        weather = self.owm.weather_at_place('XXXXXXXX,de').get_weather()
        icon = weather.get_weather_icon_name()
        temp = weather.get_temperature('celsius')
        self.rootWidget.setWeatherTemp("Max: "+str(temp['temp_max'])+" Min: "+str(temp['temp_min'])+" Curr: "+str(temp['temp']))
        self.rootWidget.setWeatherImg("http://openweathermap.org/img/w/"+icon+".png")
    @mainthread
    def updateTemp(self, args):
        self.inTemp = str(self.tempSensors["feuchte01"])
        self.outTemp = str(self.tempSensors["tempout"])
        self.testTemp = str(self.tempSensors["tempartnet"])

    def setSwitch(self, instance, value):
        try:
#            self.sendToPilight(self.deviceListByName[instance.id],value)
        except Exception,e:
            print "Error on setSwitch:",e,"\n"
    def colorChange(self, ident, instance, value):
        h = str(instance.hex_color).lstrip('#')
        dmxdata = tuple(int(h[i:i+2], 16) for i in (0, 2 ,4))
#        dmxdata = [instance.r,instance.g,instance.b]
        self.dmx.send_dmx_data(dmxdata)

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


I have no Idea how to add Objects in sub-tree defined in the KV. I've a function in MainApp which loops thru all my Switches I'll want to add into the GUI
I think I have to use the add_widget but got no Idea about how.

The GUI is running on kivypi at Raspberry Pi2 with Touchscreen and connects (IPv4) to a DMX Art Net Device and a Raspberry Pi3 to Control some Relais and Lights

ZenCODE

unread,
Oct 22, 2017, 5:08:01 PM10/22/17
to Kivy users support
Okay, I tried to add this but there is too much missing from the code above to make it runnable.Basically, you want to add an id to the container you want to add your BoxLayout's to. So in your main.kb

<RootWidget>:
    width: 800.0
    height: 480.0
    TabbedPanel:
        width: 800.0
        height: 480.0
        do_default_tab: False
        TabbedPanelItem:
            text: 'Uebersicht'
            RelativeLayout:
                Label:
                    text: ""
                    pos: 100,240
                    font_size: 20
                    id: weatherTemp
                AsyncImage:
                    id: weatherImg
                    source: "loading.png"
                    pos: 280,240
                BoxLayout:
                    orientation: 'horizontal'
                    BoxLayout:
                        id: container

Then, where you want to add then in your app, something like:

    for switch in ["SW01", "SW02", "SW03", "SW04"]:
        box = BoxLayout
        label = Label(text=switch")
        sw    = Switch(..)
        .....
        box  .add_widget(label)
        box.add_widget(sw)
        self.rootWidget.ids.container.add_widget(box)

That should get you started? Good luck :-)






Reply all
Reply to author
Forward
0 new messages