"focus" 列表中的小部件,但将光标保留在另一个列表中
"focus" widget in list but keep cursor in another
使用 urwid
,我试图将 highlight/walk 和 Pile
小部件的光标功能分开。如何使用 up/down
更改突出显示的小部件,同时将光标保持在不同的小部件中?
如果您真的需要这个,编写您自己的小部件可能是有意义的——也许基于一些 类 扩展 urwid.Text 和 urwid.Button
urwid自带的widgets中并没有真正的"highlight"功能,只有一个"focus"功能,而且要将焦点高亮与专注行为。
您可能希望通过某种辅助突出显示来实现您自己的小部件。
默认的 focus
行为将光标与属性(突出显示)行为相结合。下面的示例显示了一种解耦这些的方法,其中 SelectableIcons
列表保留突出显示功能,而光标移动到单独的 Edit
小部件。它通过以下方式执行此操作:
- 重写
keypress
方法以更新光标不在的地方的焦点
- 将每个
SelectableIcon
包装在 AttrMap
中,根据他们的 Pile's
focus_position
改变他们的 attribute
- 更改 SelectableIcon 属性后,焦点(光标)通过
focus_part='body'
设置回 Edit
小部件
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()
使用 urwid
,我试图将 highlight/walk 和 Pile
小部件的光标功能分开。如何使用 up/down
更改突出显示的小部件,同时将光标保持在不同的小部件中?
如果您真的需要这个,编写您自己的小部件可能是有意义的——也许基于一些 类 扩展 urwid.Text 和 urwid.Button
urwid自带的widgets中并没有真正的"highlight"功能,只有一个"focus"功能,而且要将焦点高亮与专注行为。
您可能希望通过某种辅助突出显示来实现您自己的小部件。
默认的 focus
行为将光标与属性(突出显示)行为相结合。下面的示例显示了一种解耦这些的方法,其中 SelectableIcons
列表保留突出显示功能,而光标移动到单独的 Edit
小部件。它通过以下方式执行此操作:
- 重写
keypress
方法以更新光标不在的地方的焦点 - 将每个
SelectableIcon
包装在AttrMap
中,根据他们的Pile's
focus_position
改变他们的 - 更改 SelectableIcon 属性后,焦点(光标)通过
focus_part='body'
设置回 self._w = ...
被调用以更新屏幕上的所有小部件
attribute
Edit
小部件
可能有更简洁的方法来做到这一点,但这应该是相当灵活的。
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()