Dropdown text selection for custom widget

50 views
Skip to first unread message

Shoumik Das

unread,
May 29, 2020, 11:23:51 AM5/29/20
to Kivy users support
Hi. I am trying to build a dropdown with custom widgets. The custom widget is basically a button derived from an image and text label in a horizontal box layout. I want to place the custom button inside a drop-down. I am testing with some sample code that I received from Eliott in this forum in an earlier thread. I have slightly modified the code to test my feature.

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
from kivy.uix.button import Button

kv
= """
<ImageLabel>:
    orientation: 'horizontal'
    Image:
        keep_ratio: True
        source: root.il_config[0]
    Label:
        markup: True
        text: root.il_config[1]


<ThreeButtons>:
    size_hint_y: None
    height: '48dp'
    Button:
        text: root.texts[0]
        on_release: app.root.ids.dropdown.select(self.text)
    Button:
        text: root.texts[1]
        on_release: app.root.ids.dropdown.select(self.text)
    Button:
        text: root.texts[2]
        on_release: app.root.ids.dropdown.select(self.text)


BoxLayout:
    orientation: 'vertical'
    Button:
        id: btn
        text: 'Press'
        on_release: dropdown.open(self)
        on_parent: dropdown.dismiss()
        size_hint_y: None
        height: '48dp'

    DropDown:
        id: dropdown
        on_select:
            btn.text = str(args[1])
            print(args[0]) # holds the DropDown object
            # args[1] holds the actual button text
        Button:
            text: 'First Item'
            size_hint_y: None
            height: '48dp'
            on_release: dropdown.select('First Item')
        ThreeButtons:
            texts: '1', '2', '3'
        ThreeButtons:
            texts: '4', '5', '6'
        ThreeButtons:
            texts: '7', '8', '9'
           
    Label:
        text: 'This is a DropDown Test'
    ImageLabel:
        id: test_imagelabel1
        il_config: 'twitter-96.png', 'Twitter Label'
    ImageLabel:
        id: test_imagelabel2
        il_config: 'linkedin-2-96.png', 'LinkedIn Label'
    ImageLabel:
        id: default_imagelabel
    ImageLabelButton:
        id: il_button1
        il_config: 'twitter-96.png', 'Twitter Label'
        on_release:
            app.root.ids.dropdown.select('Twitter Button')
            print(args[0])
    ImageLabelButton:
        id: il_button2
"""


class ThreeButtons(BoxLayout):
    texts
= ListProperty(['0','0','0'])


class ImageLabel(BoxLayout):
    il_config
= ListProperty(['atlas://data/images/defaulttheme/audio-volume-high','text'])

class ImageLabelButton(ImageLabel, Button):
   
pass


class DDApp(App):
   
def build(self):
       
return Builder.load_string(kv)


DDApp().run()

Currently, when I press theImageLabelButton, the following statement populates the dropdown text:

on_release: app.root.ids.dropdown.select('Twitter Button')

What I would like to do is let the dropdown populate the select value from the text property of the custom widget. How can I achieve this? I do not want to hard code the return value. E.g: 'Twitter Button'. I did look up the reserved keywords list for args:


The documentation states:

This keyword is available in on_<action> callbacks. It refers to the arguments passed to the callback.

When I print args[0], I get the ImageLabelButton object. If I print args[1], I get the following error:

IndexError: tuple index out of range

Can you please advise what I might be doing wrong?

Shoumik Das

unread,
May 29, 2020, 11:43:18 AM5/29/20
to Kivy users support
Ok, so it seems I made some progress and I am sharing it here.

DropDown:
        id
: dropdown
        on_select
:
            btn
.text = str(args[1])
           
print(args[0]) # holds the DropDown object
           
# args[1] holds the actual button text
       
Button:
            text
: 'First Item'
            size_hint_y
: None
            height
: '48dp'
            on_release
: dropdown.select('First Item')
       
ThreeButtons:
            texts
: '1', '2', '3'
       
ThreeButtons:
            texts
: '4', '5', '6'
       
ThreeButtons:
            texts
: '7', '8', '9'

       
ImageLabelButton:
            id
: test_imglblbtn
            size_hint_y
: None
            height
: '48dp'
            on_release
:
                dropdown
.select(self.il_config[1])

But I would still like to understand if this can be managed using the args variable in the following statement:

btn.text = str(args[1])


Thanks in advance

Elliot Garbus

unread,
May 29, 2020, 4:32:37 PM5/29/20
to kivy-...@googlegroups.com

Some edits to help you along.  The biggest changes are to the   ImageLabelButton and the ImageLabel. 

ImageLabel was changed to use source and text, so the api is more like other kivy widgets.  I also added a background color on the canvas.  Image label was not sized previously, that can cause issues.

To make the ImageLabel behave like a button (add on_press and on_release) you use ButtonBehavior,

 

 

 
 
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty, StringProperty
from kivy.uix.behaviors import ButtonBehavior

kv =
"""
<ImageLabel>:
    orientation: 'horizontal'
    size_hint_y: None
    height: '48dp'
    canvas:
        Color:
            rgb: .3, .3, .4
        Rectangle:
            pos: self.pos
            size: self.size

    Image:
        keep_ratio: True
        source: root.source
    Label:
        markup: True
        text: root.text

<ImageLabelButton>:
    on_release: app.root.ids.dropdown.select(self.text)
            print(args) # print the contents of args

            # args[1] holds the actual button text
        Button:
            text: 'First Item'
            size_hint_y: None
            height: '48dp'
            on_release: dropdown.select('First Item')
        ThreeButtons:
            texts: '1', '2', '3'
        ThreeButtons:
            texts: '4', '5', '6'
        ThreeButtons:
            texts: '7', '8', '9'
        ImageLabelButton:
            id: test_imglblbtn
            text: 'Image Label Button 1'
        ImageLabelButton:
            id: il_button1
            #il_config: 'twitter-96.png', 'Twitter Label'
            text: 'Twitter Label'
            source: 'twitter-96.png'

        ImageLabelButton:
            id: il_button2
            text: 'Another Social Network'
            source: 'twitter-96.png'

    Label:
        text: 'This is a DropDown Test'

"""


class ThreeButtons(BoxLayout):
    texts = ListProperty([
'0', '0', '0'])


class ImageLabel(BoxLayout):
    il_config = ListProperty([
'atlas://data/images/defaulttheme/audio-volume-high', 'text'
])
    source = StringProperty(
'atlas://data/images/defaulttheme/audio-volume-high')
    text = StringProperty(
'default text')


class ImageLabelButton(ButtonBehavior, ImageLabel):
   
pass

class
DDApp(App):
   
def build(self):
       
return Builder.load_string(kv)


DDApp().run()

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/fa07fad7-2a02-465d-94de-0b2a6b26c676%40googlegroups.com.

 

Shoumik Das

unread,
May 30, 2020, 1:51:27 AM5/30/20
to Kivy users support
That was perfect. Thank you so much for the help.

To unsubscribe from this group and stop receiving emails from it, send an email to kivy-...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages