2016-01-06 20 views
6

Sto usando urwid, che è un "framework" Python per la progettazione di interfacce utente terminali in ncurses. C'è una cosa però che non sono in grado di fare in urw che è stato facile in maledizioni - rendere il cursore invisibile. Come è ora, il cursore è visibile quando si selezionano i pulsanti, e sembra semplicemente brutto. C'è un modo per disabilitarlo?Urwid: rende invisibile il cursore

risposta

2

urwid utilizza la funzione curs_set, ma non lo 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.

È possibile segnalare come issue.

+1

Vedo. Ho pubblicato un problema lì, spero che gli sviluppatori lo considereranno. – makos

+0

Link al problema: https://github.com/urwid/urwid/issues/170 –

2

Concordo sul fatto che il cursore lampeggiante su un urwid.Button sembra un po 'debole, quindi ho trovato una soluzione per nasconderlo. In urwid, la classe Button è solo una sottoclasse di WidgetWrap contenente uno SelectableIcon e due widget di testo (il che include "<" e ">"). È la classe SelectableIcon che imposta la posizione del cursore sul primo carattere dell'etichetta, per impostazione predefinita. Con la sottoclasse di SelectableIcon, modificando la posizione del cursore e quindi avvolgendola in una sottoclasse urwid.WidgetWrap, è possibile creare un proprio pulsante personalizzato in grado di eseguire tutti i trucchi a Button incorporato o più.

Ecco come appare nel mio progetto.

enter image description here

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, è possibile avvolgere un oggetto ButtonLabel insieme ad altri oggetti in un WidgetWrap sottoclasse che sarà la classe pulsante personalizzato.

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, non c'è in realtà molto combinazione di widget nella sottoclasse FixedButtonWidgetWrap, ma si potrebbe aggiungere un "[" e "]" per i bordi del tasto, avvolgerlo in un LineBox, ecc. Se tutto questo è superfluo, puoi semplicemente spostare le funzioni di gestione degli eventi nella classe ButtonLabel e fargli emettere un segnale quando viene cliccato.

Per rendere il pulsante invertita quando l'utente si sposta su di essa, avvolgono in AttrMap e impostare il focus_map a qualche voce di tavolozza ("button_reversed", nel mio caso).

0

Lungo le linee di risposta di Drunken Master, ma con "chirurgia minimamente invasiva":

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) 

Qui, modificare solo l'aspetto del pulsante ma per il resto lasciare il suo comportamento invariato.