1

使用urwid,我试图分离Pile小部件的突出显示/步行和光标功能。如何使用up/down更改突出显示的小部件,同时将光标保持在不同的小部件中?

4

2 回答 2

2

默认focus行为将光标与属性(突出显示)行为结合起来。下面的示例显示了一种解耦它们的方法,其中列表SelectableIcons保留突出显示功能,而光标移动到单独的Edit小部件。它通过以下方式做到这一点:

  • 重写keypress方法以更新光标不在的焦点
  • 根据他们的SelectableIcon变化AttrMap包装每一个attributePile's focus_position
  • 更改 SelectableIcon 属性后,焦点(光标)通过以下方式设置回Edit小部件focus_part='body'
  • self._w = ...调用以更新屏幕上的所有小部件

可能有更简洁的方法可以做到这一点,但这应该是相当灵活的。

import urwid

def main():
    my_widget = MyWidget()
    palette = [('unselected', 'default', 'default'),
               ('selected', 'standout', 'default', 'bold')]

    urwid.MainLoop(my_widget, palette=palette).run()


class MyWidget(urwid.WidgetWrap):

    def __init__(self):

        n = 10       
        labels = ['selection {}'.format(j) for j in range(n)]

        self.header = urwid.Pile([urwid.AttrMap(urwid.SelectableIcon(label), 'unselected', focus_map='selected') for label in labels])

        self.edit_widgets = [urwid.Edit('', label + ' edit_text') for label in labels]

        self.body = urwid.Filler(self.edit_widgets[0])

        super().__init__(urwid.Frame(header=self.header, body=self.body, focus_part='body'))

        self.update_focus(new_focus_position=0)

    def update_focus(self, new_focus_position=None):
        self.header.focus_item.set_attr_map({None: 'unselected'})

        try:
            self.header.focus_position = new_focus_position
            self.body = urwid.Filler(self.edit_widgets[new_focus_position])

        except IndexError:
            pass

        self.header.focus_item.set_attr_map({None: 'selected'})

        self._w = urwid.Frame(header=self.header, body=self.body, focus_part='body')

    def keypress(self, size, key):

        if key == 'up':
            self.update_focus(new_focus_position=self.header.focus_position - 1)

        if key == 'down':
            self.update_focus(new_focus_position=self.header.focus_position + 1)

        if key in {'Q', 'q'}:
            raise urwid.ExitMainLoop()

        super().keypress(size, key)

main()
于 2018-03-27T19:01:39.187 回答
1

如果你真的需要这个,编写你自己的小部件可能是有意义的——也许基于一些扩展 urwid.Text 和 urwid.Button 的类

urwid 自带的widget 中并没有真正的“高亮”功能,只有一个“焦点”功能,而且将焦点高亮与焦点行为解耦似乎并不容易。

您可能希望使用某种辅助突出显示来实现自己的小部件。

于 2018-03-26T17:57:30.130 回答