2017-12-03 13 views
2

사용자가 H 키를 누를 때 urwid 응용 프로그램 위에 도움말 대화 상자를 표시하려고 시도하지만이를 사라지게 할 수 없습니다. 문제없이 표시됩니다. 내가 뭘 놓치고 있니? 나는 지금 하루 종일 좋은 부분을 보냈다.Urwid keyboard triggered popup

여러 구현 예를 살펴 보았습니다. 나는 신호로 놀았지만 아무 소용이 없다. 도움을 얻을 수있는 버튼이 없도록하고 키보드 바로 가기에만 의존하고 싶습니다.

import urwid 

class Application(object): 
    ''' 
    The console UI 
    ''' 

    # The default color palette 
    _palette = [ 
     ('banner', 'black', 'light gray'), 
     ('selectable', 'white', 'black'), 
     ('focus', 'black', 'light gray') 
    ] 

    def __init__(self): 
     self._content = [ 
      urwid.Text('Initializing...', align = 'left') 
     ] 

     # Body 
     self._body_walker = urwid.SimpleListWalker(self._content) 
     self._body_list = urwid.ListBox(self._body_walker) 
     self._body_padding = urwid.Padding(
      self._body_list, 
      left = 1, 
      right = 1 
     ) 
     self._body = urwid.LineBox(self._body_padding) 

     # Loop 
     self._loop = urwid.MainLoop(
      self._body, 
      self._palette, 
      unhandled_input = self._handle_input 
     ) 

    def reset_layout(self): 
     ''' 
     Resets the console UI to the default layout 
     ''' 

     self._loop.widget = self._body 
     self._loop.draw_screen() 

    def _handle_input(self, key): 
     ''' 
     Handles user input to the console UI 

     Args: 
      key (object): A mouse or keyboard input sequence 
     ''' 

     if type(key) == str: 
      if key in ('q', 'Q'): 
       raise urwid.ExitMainLoop() 
      elif key in ('h', 'H'): 
       self.dialog(
        [ 
         'Urwid v1.3.1\n', 
         '\n', 
         'Press Q to quit\n', 
         'Press H for help' 
        ] 
       ) 
     elif type(key) == tuple: 
      pass 

    def print(self, string = '', align = 'left'): 
     ''' 
     Prints a string to the console UI 

     Args: 
      string (str): The string to print 
      align (str): The alignment of the printed text 
     ''' 

     self._body_walker.append(
      urwid.Text(string, align = align) 
     ) 

    def printf(self, *strings): 
     ''' 
     Prints multiple strings with different alignment 

     Args: 
      strings (tuple): A string, alignment pair 
     ''' 

     self._body_walker.append(
      urwid.Columns(
       [ 
        urwid.Text(string, align = align) 
        for string, align in strings 
       ] 
      ) 
     ) 

    def start(self): 
     ''' 
     Starts the console UI 
     ''' 

     self._loop.run() 

    def dialog(self, text = ['']): 
     ''' 
     Overlays a dialog box on top of the console UI 

     Args: 
      test (list): A list of strings to display 
     ''' 

     # Header 
     header_text = urwid.Text(('banner', 'Help'), align = 'center') 
     header = urwid.AttrMap(header_text, 'banner') 

     # Body 
     body_text = urwid.Text(text, align = 'center') 
     body_filler = urwid.Filler(body_text, valign = 'top') 
     body_padding = urwid.Padding(
      body_filler, 
      left = 1, 
      right = 1 
     ) 
     body = urwid.LineBox(body_padding) 

     # Footer 
     footer = urwid.Button('Okay', self.reset_layout()) 
     footer = urwid.AttrWrap(footer, 'selectable', 'focus') 
     footer = urwid.GridFlow([footer], 8, 1, 1, 'center') 

     # Layout 
     layout = urwid.Frame(
      body, 
      header = header, 
      footer = footer, 
      focus_part = 'footer' 
     ) 

     w = urwid.Overlay(
      urwid.LineBox(layout), 
      self._body, 
      align = 'center', 
      width = 40, 
      valign = 'middle', 
      height = 10 
     ) 

     self._loop.widget = w 

Application().start() 

답변

2

당신은 내가 할 필요가 모든 버튼의 콜백에 괄호를 삭제했다 실현 후 지금 기분 바보 상상할 수 있습니까?

footer = urwid.Button('Okay', self.reset_layout)

다음은 앞으로이에 비틀 거리고 누구에 놀러 좀 더 많은 샘플 코드입니다.

import urwid 

class Application(object): 
    ''' 
    The console UI 
    ''' 

    # The default color palette 
    _palette = [ 
     ('banner', 'black', 'light gray'), 
     ('selectable', 'white', 'black'), 
     ('focus', 'black', 'light gray') 
    ] 

    def __init__(self): 
     self._body = urwid.SolidFill('.') 
     self._pile = urwid.Pile(
      [ 
       self.dialog() 
      ] 
     ) 
     self._over = urwid.Overlay(
      self._pile, 
      self._body, 
      align = 'center', 
      valign = 'middle', 
      width = 20, 
      height = 10 
     ) 

     # Loop 
     self._loop = urwid.MainLoop(
      self._over, 
      self._palette, 
      unhandled_input = self._handle_input 
     ) 

    def _handle_input(self, key): 
     ''' 
     Handles user input to the console UI 

     Args: 
      key (object): A mouse or keyboard input sequence 
     ''' 

     if type(key) == str: 
      if key in ('q', 'Q'): 
       raise urwid.ExitMainLoop() 
     elif type(key) == tuple: 
      pass 

    def start(self): 
     ''' 
     Starts the console UI 
     ''' 

     self._loop.run() 

    def do(self, thing): 
     self._loop.widget = self._body 
     #self._pile.contents.clear() 

    def dialog(self): 
     ''' 
     Overlays a dialog box on top of the console UI 
     ''' 

     # Header 
     header_text = urwid.Text(('banner', 'Help'), align = 'center') 
     header = urwid.AttrMap(header_text, 'banner') 

     # Body 
     body_text = urwid.Text('Hello world', align = 'center') 
     body_filler = urwid.Filler(body_text, valign = 'top') 
     body_padding = urwid.Padding(
      body_filler, 
      left = 1, 
      right = 1 
     ) 
     body = urwid.LineBox(body_padding) 

     # Footer 
     footer = urwid.Button('Okay', self.do) 
     footer = urwid.AttrWrap(footer, 'selectable', 'focus') 
     footer = urwid.GridFlow([footer], 8, 1, 1, 'center') 

     # Layout 
     layout = urwid.Frame(
      body, 
      header = header, 
      footer = footer, 
      focus_part = 'footer' 
     ) 

     return layout 

Application().start()