selectable_row.py
 1  #! /usr/bin/env python3
 2  # -*- coding: utf-8 -*-
 3  
 4  
 5  import urwid
 6  
 7  
 8  class SelectableRow(urwid.WidgetWrap):
 9      """Wraps 'urwid.Columns' to make it selectable.
10      This class has been slightly modified, but essentially corresponds to this class posted on stackoverflow.com:
11      https://stackoverflow.com/questions/52106244/how-do-you-combine-multiple-tui-forms-to-write-more-complex-applications#answer-52174629"""
12  
13      def __init__(self, contents, *, align="left", on_select=None, space_between=2):
14          # A list-like object, where each element represents the value of a column.
15          self.contents = contents
16          
17          self._columns = urwid.Columns([urwid.Text(c, align=align) for c in contents],
18                                         dividechars=space_between)
19          
20          # Wrap 'urwid.Columns'.
21          super().__init__(self._columns)
22          
23          # A hook which defines the behavior that is executed when a specified key is pressed.
24          self.on_select = on_select
25      
26      def __repr__(self):
27          return "{}(contents='{}')".format(self.__class__.__name__,
28                                            self.contents)
29      
30      def selectable(self):
31          return True
32      
33      def keypress(self, size, key):
34          if (key == "enter") and (self.on_select is not None):
35              self.on_select(self)
36              key = None
37              
38          return key
39      
40      def set_contents(self, contents):
41          # Update the list record inplace...
42          self.contents[:] = contents
43          
44          # ... and update the displayed items.
45          for t, (w, _) in zip(contents, self._columns.contents):
46              w.set_text(t)
47