python-prompt-toolkit: make container scrollable

953 views Asked by At

I am trying to make a Container scrollable using ScrollablePane.But I can't scroll either with mouse or keyboard

from prompt_toolkit.layout.controls import FormattedTextControl
from prompt_toolkit import Application
from prompt_toolkit.layout import ScrollablePane
from prompt_toolkit.layout.layout import Layout
from prompt_toolkit.layout.containers import HSplit, VSplit, Window

content = HSplit(
  [
    VSplit(
      [Window(FormattedTextControl('First Column')),
      Window(FormattedTextControl('Second Column'))
      ]),
    VSplit(
      [Window(FormattedTextControl('First Column')),
      Window(FormattedTextControl('Second Column'))
      ]),
    VSplit(
      [Window(FormattedTextControl('First Column')),
      Window(FormattedTextControl('Second Column'))
      ]),
  ])
container = ScrollablePane(content=content)

app = Application(layout=Layout(container), full_screen=True)
app.run()
1

There are 1 answers

0
Kozmik Moore On

First, you should enable mouse_support in app:

app = Application(mouse_support=True,...)

That does not actually seem to make the ScrollablePane scrollable with the mousewheel or using the arrows. I have yet to find a solution for this.

I have found that stacking a bunch of focusable elements (e.g. Window) within the ScrollablePane and assigning a keyboard shortcut to change the app focus from one element to the next will scroll the pane.

Example (decrease window height or increase number to obscure part of the display):

from prompt_toolkit import Application
from prompt_toolkit.application import get_app
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.layout import HSplit, FormattedTextControl, Window, ScrollablePane, Layout

kb = KeyBindings()

number = 30

inner = HSplit(children=[Window(FormattedTextControl(text=f"Button {x}")) for x in range(number)])

index = 0


def increment_index():
    global index
    if index == number - 1:
        index = 0
    else:
        index += 1


@kb.add('n')
def _(event):
    increment_index()
    get_app().layout.focus(inner.children[index])


@kb.add('q')
def _(event):
    get_app().exit()


outer = ScrollablePane(content=inner)

app = Application(mouse_support=True, layout=Layout(outer), full_screen=True, key_bindings=kb)

app.run()