Urwid:使光标不可见
问题描述:
我正在使用urwid,它是一个用于在ncurses中设计终端用户界面的Python“框架”。有一件事,虽然我不能在诅咒中轻松实现urwid,但使光标不可见。就像现在这样,选择按钮时光标是可见的,而且看起来很丑陋。有没有办法禁用它?Urwid:使光标不可见
答
我同意在urwid.Button
上闪烁的光标看起来有点跛脚,所以我想出了一个解决方案来隐藏它。在urwid中,Button
类只是WidgetWrap
的一个子类,其中包含SelectableIcon
和两个文本小部件(包含“<”和“>”)。这是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)
接下来,你可以用任何其它物品一起裹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
在这段代码,实际上是不是在FixedButton
WidgetWrap
子控件的多组合,但你可以添加一个“[
”和“]
”的按钮的边缘,将它包装成一个LineBox
,等等。如果所有这些都是多余的,您可以将事件处理函数移动到ButtonLabel
类中,并使其在点击时发出信号。
要逆转时,其上的用户移动,把它包装成AttrMap
并设置focus_map
一些调色板项(“button_reversed
”,在我的情况)按钮。
答
随着醉拳的答案的线条,而是用“微创手术”:
class ButtonLabel(urwid.SelectableIcon):
'''
use Drunken Master's trick to move the cursor out of view
'''
def set_text(self, label):
'''
set_text is invoked by Button.set_label
'''
self.__super.set_text(label)
self._cursor_position = len(label) + 1
class MyButton(urwid.Button):
'''
- override __init__ to use our ButtonLabel instead of urwid.SelectableIcon
- make button_left and button_right plain strings and variable width -
any string, including an empty string, can be set and displayed
- otherwise, we leave Button behaviour unchanged
'''
button_left = "["
button_right = "]"
def __init__(self, label, on_press=None, user_data=None):
self._label = ButtonLabel("")
cols = urwid.Columns([
('fixed', len(self.button_left), urwid.Text(self.button_left)),
self._label,
('fixed', len(self.button_right), urwid.Text(self.button_right))],
dividechars=1)
super(urwid.Button, self).__init__(cols)
if on_press:
urwid.connect_signal(self, 'click', on_press, user_data)
self.set_label(label)
在这里,我们只能修改按钮的外观,但否则保留其行为不变。
我明白了。我在那里发布了一个问题,希望urwid devs会考虑这个问题。 – makos
问题链接:https://github.com/urwid/urwid/issues/170 –