GNU/Linux >> Linux Esercitazione >  >> Linux

Urwid:rende invisibile il cursore

Accetto che il cursore lampeggiante su un urwid.Button sembra un po 'zoppo, quindi ho trovato una soluzione per nasconderlo. In urwid, Button class è solo una sottoclasse di WidgetWrap contenente un SelectableIcon e due widget di testo (il "<" e ">" che lo racchiudono). È il SelectableIcon class che imposta la posizione del cursore sul primo carattere dell'etichetta, per impostazione predefinita. Sottoclasse SelectableIcon , modificando la posizione del cursore e quindi avvolgendolo in un urwid.WidgetWrap sottoclasse puoi creare il tuo pulsante personalizzato che può fare tutti i trucchi un Button integrato , o anche di più.

Ecco come appare nel mio progetto.

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)

Successivamente, puoi avvolgere un ButtonLabel oggetto insieme a qualsiasi altro oggetto in un WidgetWrap sottoclasse che sarà la tua classe di pulsanti personalizzati.

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

In questo codice, in realtà non c'è molta combinazione di widget nel FixedButton WidgetWrap sottoclasse, ma potresti aggiungere un "[ " e "] " ai bordi del pulsante, avvolgilo in un LineBox , ecc. Se tutto questo è superfluo, puoi semplicemente spostare le funzioni di gestione degli eventi nel ButtonLabel class e fargli emettere un segnale quando viene cliccato.

Per fare in modo che il pulsante si inverta quando l'utente si sposta su di esso, avvolgilo in AttrMap e imposta focus_map a qualche voce della tavolozza ("button_reversed ", nel mio caso).


urwid utilizza la funzione curs_set, ma non la espone come metodo di classe da nessuna parte. Qualcuno potrebbe modificare urwid per consentire l'utilizzo di questo metodo; altrimenti non esiste un metodo affidabile per farlo.

Potresti segnalarlo come un problema.


Sulla base della risposta di Drunken Master, ho ripulito la soluzione il più possibile.

Il urwid.SelectableIcon è fondamentalmente un urwid.Text campo con questo brutto cursore lampeggiante. Quindi, invece di sovrascrivere il urwid.SelectableIcon e comprimendolo in un urwid.WidgetWrap , prendiamo un urwid.Text direttamente e renderlo selezionabile e reagire all'attivazione del pulsante/mouse (ispirato al semplice tutorial del menu di 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()

Funziona a meraviglia:


Linux
  1. Far scorrere i movimenti del mouse quando si tiene premuto il pulsante centrale?

  2. Bash:Maiusc+tasti freccia Crea A,b,c,d?

  3. Fai uscire Tail -f su un tubo rotto?

  4. Linux:come rendere un processo invisibile agli altri utenti?

  5. Impostare la trasparenza della finestra in Gnome?

Crea musica su Linux con Ardor

Crea una USB persistente Kali Linux

Bash Select (Crea menu)

Come rendere eseguibile un file in Linux

Usa vi Editor

PiShrink:riduci le immagini di Raspberry Pi