prompt-toolkit / python-prompt-toolkit

Library for building powerful interactive command line applications in Python
https://python-prompt-toolkit.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
9.11k stars 717 forks source link

How do I get buttons with a scroll bar #1759

Open CelestialCipher opened 1 year ago

CelestialCipher commented 1 year ago

so I have this code

from prompt_toolkit.key_binding.bindings.focus import focus_next, focus_previous
from prompt_toolkit.layout.containers import VSplit, HSplit, Window
from prompt_toolkit.layout.controls import FormattedTextControl
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.widgets import Button
from prompt_toolkit.layout import Layout
from prompt_toolkit import Application
from functools import partial

pets = ['dog', 'cat', 'parrot']
buttons = []

kb = KeyBindings()

@kb.add('c-c')
def exit_(event):
    event.app.exit()
    sys.exit()

kb.add("tab")(focus_next)
kb.add("s-tab")(focus_previous)

formatted_text = FormattedTextControl("")

for pet in pets:
    def handler(pet_name):
        formatted_text.text = f'{pet_name} button clicked!'

    btn = Button(pet, width=len(pet), handler=partial(handler, pet), left_symbol='', right_symbol='')
    buttons.append(btn)

root_container = VSplit(
        [
            HSplit(buttons),
            Window(width=1, char="|"),
            Window(formatted_text)

        ],
        padding=1
)

layout = Layout(root_container)
application = Application(layout=layout, key_bindings=kb, full_screen=True, mouse_support=True,)

application.run()

my problem is if I make the list bigger like pets = ['dog', 'cat', 'parrot']*100 it fails and gives "Window is too small". So I want to add a scrollbar next to it which allows me to scroll through the buttons, how do I do that?

joouha commented 12 months ago

Try wrapping your HSplit(buttons) in a ScrollablePane:


...

from prompt_toolkit.layout.scrollable_pane import ScrollablePane

...

root_container = VSplit(
        [
            ScrollablePane(HSplit(buttons)),
            Window(width=1, char="|"),
            Window(formatted_text)

        ],
        padding=1
)

...