Urwid: сделать курсор невидимым
Я использую urwid, который является "фреймворком" Python для разработки терминальных пользовательских интерфейсов в ncurses. Однако есть одна вещь, которую я не могу сделать в urwid, что было легко в проклятиях - сделать курсор невидимым. Как и сейчас, курсор виден при выборе кнопок,и он просто выглядит уродливым. Есть ли способ отключить его?
3 ответов
я согласен, что мигающий курсор на urwid.Button
выглядит немного коряво, поэтому я придумал решение, чтобы скрыть это. В urwid, в Button
class - это просто подкласс 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
, etc. Если все это излишне, вы можете просто переместить функции обработки событий в ButtonLabel
class, и сделать его испускать сигнал, когда он нажмет.
чтобы сделать кнопку обратной, когда пользователь перемещается по ней, оберните ее в 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)
здесь мы только изменяем внешний вид кнопки, но в противном случае оставляем ее поведение неизменным.