列表中的“焦点”小部件,但将光标保留在另一个

时间:2018-03-21 20:54:36

标签: widget focus urwid

使用urwid,我正在尝试分离Pile小部件的高亮/漫游和光标功能。如何使用up/down更改突出显示的窗口小部件,同时将光标保持在不同的窗口小部件中?

2 个答案:

答案 0 :(得分:1)

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

在urwid附带的小部件中没有真正的“突出显示”功能,只有一个“焦点”功能,并且将焦点高光与焦点行为分离似乎并不容易。

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

答案 1 :(得分:1)

默认focus行为将光标与属性(突出显示)行为结合在一起。下面的示例显示了一种解耦这些问题的方法,其中SelectableIcons列表保留突出显示功能,同时将光标移动到单独的Edit窗口小部件。它通过以下方式实现:

  • 覆盖keypress方法以更新光标不在的焦点
  • 根据SelectableIcon AttrMap
  • attribute中的每个Pile's打包,以更改focus_position Edit
  • 更改SelectableIcon属性后,焦点(光标)通过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() 来更新屏幕上的所有小部件

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

library(dplyr)
library(lubridate)

df %>% 
  mutate(since_midnight = hour(timestamp) * 60 + minute(timestamp)) %>% 
  filter(since_midnight >= 9*60 & since_midnight < (20 * 60 + 15)) %>% 
  summarise(mean = mean(value))