GNU/Linux >> Tutoriales Linux >  >> Linux

Urwid:hacer el cursor invisible

Acepto que el cursor parpadeante en un urwid.Button parece un poco tonto, así que he encontrado una solución para ocultarlo. En urwid, el Button la clase es solo una subclase de WidgetWrap que contiene un SelectableIcon y dos widgets de texto (los "<" y ">" adjuntos). Es el SelectableIcon clase que establece la posición del cursor en el primer carácter de la etiqueta, de forma predeterminada. Subclasificando SelectableIcon , modificando la posición del cursor y luego envolviéndolo en un urwid.WidgetWrap subclase puede crear su propio botón personalizado que puede hacer todos los trucos de un Button incorporado , o incluso más.

Esto es lo que parece en mi proyecto.

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)

A continuación, puede envolver un ButtonLabel objeto junto con cualquier otro objeto en un WidgetWrap subclase que será su clase de botón personalizado.

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

En este código, en realidad no hay mucha combinación de widgets en el FixedButton WidgetWrap subclase, pero podría agregar un "[ " y "] " hasta los bordes del botón, envuélvelo en un LineBox , etc. Si todo esto es superfluo, simplemente puede mover las funciones de manejo de eventos al ButtonLabel clase, y hacer que emita una señal cuando se hace clic.

Para hacer que el botón se invierta cuando el usuario se mueve sobre él, envuélvelo en AttrMap y establece el focus_map a alguna entrada de paleta ("button_reversed ", en mi caso).


urwid usa la función curs_set, pero no la expone como un método de clase en ninguna parte. Alguien podría modificar urwid para permitir el uso de este método; de lo contrario, no existe un método confiable para hacerlo.

Puede reportarlo como un problema.


Sobre la base de la respuesta de Drunken Master, he limpiado la solución tanto como sea posible.

El urwid.SelectableIcon es básicamente un urwid.Text campo con este feo cursor parpadeante. Entonces, en lugar de anular el urwid.SelectableIcon y empaquetarlo en un urwid.WidgetWrap , tomemos un urwid.Text directamente y hacerlo seleccionable y reaccionar a la activación del botón/ratón (inspirado en el sencillo tutorial de menú de urwid):

import urwid

choices = u'Chapman Cleese Gilliam Idle Jones Palin'.split()

class ListEntry(urwid.Text):
    _selectable = True

    signals = ["click"]

    def keypress(self, size, key):
        """
        Send 'click' signal on 'activate' command.
        """
        if self._command_map[key] != urwid.ACTIVATE:
            return key

        self._emit('click')

    def mouse_event(self, size, event, button, x, y, focus):
        """
        Send 'click' signal on button 1 press.
        """
        if button != 1 or not urwid.util.is_mouse_press(event):
            return False

        self._emit('click')
        return True

def menu(title, choices):
    body = [urwid.Text(title), urwid.Divider()]
    for c in choices:
        button = ListEntry(c)
        urwid.connect_signal(button, 'click', item_chosen, c)
        body.append(urwid.AttrMap(button, None, focus_map='reversed'))
    return urwid.ListBox(urwid.SimpleFocusListWalker(body))

def item_chosen(button, choice):
    response = urwid.Text([u'You chose ', choice, u'\n'])
    done = ListEntry(u'Ok')
    urwid.connect_signal(done, 'click', exit_program)
    main.original_widget = urwid.Filler(urwid.Pile([response,
                                                    urwid.AttrMap(done, None, focus_map='reversed')]))

def exit_program(button):
    raise urwid.ExitMainLoop()

main = urwid.Padding(menu(u'Pythons', choices), left=2, right=2)
top = urwid.Overlay(main, urwid.SolidFill(u'\N{MEDIUM SHADE}'),
                    align='center', width=('relative', 60),
                    valign='middle', height=('relative', 60),
                    min_width=20, min_height=9)
urwid.MainLoop(top, palette=[('reversed', 'standout', '')]).run()

Funciona de maravilla:


Linux
  1. Cómo solucionar el problema del cursor del mouse invisible en Ubuntu GNOME

  2. ¿Hacer que los movimientos del mouse se desplacen cuando se mantiene presionado el botón central?

  3. ¿Movimiento del cursor en las terminales?

  4. Cómo hacer una VPN

  5. ¿Cómo hacer que el archivo sea disperso?

Haz música en Linux con Ardor

Hacer un USB persistente de Kali Linux

Bash Select (hacer menús)

Cómo hacer un archivo ejecutable en Linux

Usar el editor vi

PiShrink:reduce el tamaño de las imágenes de Raspberry Pi