0

Hi Guys I have a question about kivy DropDown. I have this example:

def dropdownbutton(self):
    dropdown = DropDown()
    classlist = ['Barbarian', 'Knight', 'Sorcerer', 'Typical Seba', 'Hunter']
    for index in classlist:
        btn = Button(text='%s' % index, size_hint_y=None, height=44)
        btn.bind(on_release=lambda btn: dropdown.select(btn.text))
        dropdown.add_widget(btn)
    mainbutton = Button(text='Class', size_hint=(None, None))
    mainbutton.bind(on_release=dropdown.open)
    dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text',
                                                        x))  
    return mainbutton

And what I want to do, is to track current btn.txt which I choose, mby its dumb, but I spend about hour on this... Can you help me? btn.text returns me Hunter all the time

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
Moyaa
  • 61
  • 2
  • 3
  • I don't have a clue what your issue is. The default button has text `Class`, returns the splitted `classlist` as buttons in `DropDown` and on click at the dropdown button the text changes properly. Any more explanation, screenshot or more code, please? – Peter Badida Nov 13 '16 at 15:31
  • Yes, you are right, text changes properly on `DropDown` button, but I need to store text from button in different variable, to initiate class **base** on chosen button :) For Example if I choose button `Knight` i want to create instance of `class Knight` with `btn.text`, and i know how to do it, but I can't retrieve current `btn.text` – Moyaa Nov 13 '16 at 15:41

2 Answers2

0

You've hit this classic problem with defining lambda functions in a loop. Try:

btn.bind(on_release=lambda btn=btn: dropdown.select(btn.text))
Community
  • 1
  • 1
inclement
  • 29,124
  • 4
  • 48
  • 60
  • I don't think so, I think that the problem is in this line: `dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))` In here we set text to the `mainbutton` but also I want to put chosen `btn.text` to variable and use it other way. – Moyaa Nov 13 '16 at 15:59
0

So I made kind of work around with this class:

class DropdownList(Button):

    def __init__(self, label, labels):
        Button.__init__(self,
                        text=label,
                        size_hint=(None, None))

        self.buttons = []
        self.list = DropDown()

        for label in labels:
            b = Button(text=label, notify=None, callback=None)
            b.size_hint = (None, None)
            self.buttons.append(b)
            self.list.add_widget(b)

        self.bind(on_release=self.list.open)`

With this class I can attach special behavior to every button like this:

def build(self):
        classlist = ['Barbarian', 'Knight', 'Sorcerer', 'Typical Seba', 'Hunter']
        self.lst = DropdownList("Class", classlist)
        self.lst.buttons[0].bind(on_release=self.randomfunction)
        print self.lst.buttons[0].text

In behavior method I have to pass event as a argument:

def randomfunction(self, event):
        print "random string"

But there is still few problems here. I can't setattr to change text of the self.list DropDown button. Am'I missing something here? I just want to have two behavior's on every button. One: to take text from chosen button and put it to DropDown button, and close it. Second: with text from chosen button create instance of class with the same name as button... I will leave it like it is for now, but if anyone can solve it it will be great

Moyaa
  • 61
  • 2
  • 3