我同意 an 上闪烁的光标urwid.Button看起来有点蹩脚,所以我想出了一个解决方案来隐藏它。在 urwid 中,Button该类只是WidgetWrap包含一个SelectableIcon和两个 Text 小部件(封闭的“<”和“>”)的子类。SelectableIcon默认情况下,该类将光标位置设置为标签的第一个字符。通过子类化SelectableIcon,修改光标位置,然后将其包装到urwid.WidgetWrap子类中,您可以创建自己的自定义按钮,该按钮可以执行内置的所有技巧Button,甚至更多。
这是我的项目中的样子。
import urwid
class ButtonLabel(urwid.SelectableIcon):
def __init__(self, text):
"""
Here's the trick:
we move the cursor out to the right of the label/text, so it doesn't show
"""
curs_pos = len(text) + 1
urwid.SelectableIcon.__init__(self, text, cursor_position=curs_pos)
Run Code Online (Sandbox Code Playgroud)
接下来,您可以将一个ButtonLabel对象与任何其他对象一起包装到一个WidgetWrap子类中,该子类将成为您的自定义按钮类。
class FixedButton(urwid.WidgetWrap):
_selectable = True
signals = ["click"]
def __init__(self, label):
self.label = ButtonLabel(label)
# you could combine the ButtonLabel object with other widgets here
display_widget = self.label
urwid.WidgetWrap.__init__(self, urwid.AttrMap(display_widget, None, focus_map="button_reversed"))
def keypress(self, size, key):
"""
catch all the keys you want to handle here
and emit the click signal along with any data
"""
pass
def set_label(self, new_label):
# we can set the label at run time, if necessary
self.label.set_text(str(new_label))
def mouse_event(self, size, event, button, col, row, focus):
"""
handle any mouse events here
and emit the click signal along with any data
"""
pass
Run Code Online (Sandbox Code Playgroud)
在这段代码中,FixedButton WidgetWrap子类中的小部件组合实际上并不多,但是您可以在按钮的边缘添加一个“ [”和“ ]”,将其包装成一个LineBox等。如果这一切都是多余的,您可以移动事件处理函数进入ButtonLabel类,并使其在被点击时发出信号。
要在用户移动按钮时反转按钮,请将其包装AttrMap并设置focus_map为某个调色板条目(button_reversed在我的情况下为“ ”)。