pythonuser-interfaceenaml

How to create a Multi-item selection dropdown list?


I want to create a multi-item selection drop-down in enaml.

ComboBox widget offers this but we can only select one item at a time. Same is the case with ObjectCombo widget (however slightly different in functionality from ComboBox).

Even something which closely replicates the end-functionality of being able to select multi items from a list, will be helpful, even if it's not a drop-down necessarily.


Solution

  • You can use the PopupMenu and make the actions checkable.

    enaml multi select menu

    Like this:

    #------------------------------------------------------------------------------
    # Copyright (c) 2018, Nucleic Development Team.
    #
    # Distributed under the terms of the Modified BSD License.
    #
    # The full license is in the file COPYING.txt, distributed with this software.
    #------------------------------------------------------------------------------
    """ This example demonstrates how to popup a menu.
    
    A menu can be popped up in 2-ways. The first is by declaring the menu as
    a child of a widget and setting the 'context_menu' attribute to True. The
    second method is by creating the menu on-demand, and then invoking it's
    'popup()' method to show the menu at the current mouse location.
    
    
    """
    from __future__ import print_function
    from enaml.widgets.api import (
        Window, Container, PushButton, Menu, Action, Field
    )
    from enaml.core.api import Looper
    
    enamldef PopupMenu(Menu): menu:
        attr selected = set()
        attr choices = []
        Looper:
            iterable << choices
            Action:
                text = loop_item
                triggered :: print(text + ' triggered')
                checkable = True
                checked << self.text in selected
                checked ::  selected.add(self.text) if self.checked else selected.remove(self.text)
    
    
    enamldef Main(Window):
        Container:
            PushButton:
                text = 'Popup Menu'
                attr selected = set()
                clicked :: PopupMenu(selected=self.selected,
                                     choices=['foo', 'bar', 'baz', 'bam']).popup()
            Field:
                text = 'Context Menu'
                read_only = True
                PopupMenu:
                    context_menu = True
                    choices = ['a', 'b', 'c', 'd']