Python Urwid键盘触发弹出窗口

Python Urwid键盘触发弹出窗口,python,console-application,urwid,Python,Console Application,Urwid,当用户按下H键时,我试图在我的urwid应用程序上方显示一个帮助对话框,但我似乎无法让它消失。它显示时没有问题。我错过了什么?我已经干了一整天了 我看了几个例子,描述了实现这一点的不同方法。我一直在玩弄信号,但没用。我希望避免有一个可视的按钮来寻求帮助,而仅仅依靠键盘快捷键 import urwid class Application(object): ''' The console UI ''' # The default color palette

当用户按下H键时,我试图在我的urwid应用程序上方显示一个帮助对话框,但我似乎无法让它消失。它显示时没有问题。我错过了什么?我已经干了一整天了

我看了几个例子,描述了实现这一点的不同方法。我一直在玩弄信号,但没用。我希望避免有一个可视的按钮来寻求帮助,而仅仅依靠键盘快捷键

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()

你能想象当我意识到我所需要做的只是在按钮的回调上放上括号后,我现在感觉有多愚蠢吗

footer=urwid.Button('ok',self.reset\u布局)

这里有更多的示例代码供将来偶然发现的人使用

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()