2016-01-06 15 views
6

Ich benutze Urwid, das ist ein Python "Framework" für den Entwurf von Terminal-Benutzeroberflächen in Ncurses. Es gibt jedoch eine Sache, die ich in urwid nicht machen kann, die in Flüchen einfach war - mache den Cursor unsichtbar. Wie es jetzt ist, ist der Cursor sichtbar, wenn man Tasten auswählt, und es sieht einfach hässlich aus. Gibt es eine Möglichkeit, es zu deaktivieren?Urwid: Cursor unsichtbar machen

Antwort

2

urwid verwendet die curs_set-Funktion, stellt sie jedoch nicht als Klassenmethode zur Verfügung. Jemand könnte urwid ändern, um die Verwendung dieser Methode zu ermöglichen. Ansonsten gibt es keine zuverlässige Methode, dies zu tun.

Sie könnten dies als issue melden.

+1

Ich sehe. Ich habe dort ein Problem gepostet, hoffentlich werden Entwickler dies berücksichtigen. – makos

+0

Link zum Problem: https://github.com/urwid/urwid/issues/170 –

2

Ich stimme zu, dass der blinkende Cursor auf einem urwid.Button ein bisschen lahm aussieht, also habe ich eine Lösung gefunden, um es zu verstecken. In urwid ist die Button Klasse nur eine Unterklasse von WidgetWrap enthält eine SelectableIcon und zwei Text-Widgets (die umschließenden "<" und ">"). Es ist die Klasse SelectableIcon, die die Cursorposition standardmäßig auf das erste Zeichen der Beschriftung einstellt. Durch Unterklassen SelectableIcon, Ändern der Cursor-Position und dann Wrapping in eine urwid.WidgetWrap Unterklasse können Sie Ihre eigene benutzerdefinierte Schaltfläche erstellen, die alle Tricks eine eingebaute Button oder noch mehr tun können.

Hier, wie es in meinem Projekt aussieht.

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) 

Als Nächstes können Sie ein ButtonLabel Objekt zusammen mit anderen Objekten in eine WidgetWrap Unterklasse wickeln, die Ihre benutzerdefinierte Schaltfläche Klasse sein wird.

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 diesem Code gibt eigentlich nicht viel Kombination von Widgets in der FixedButtonWidgetWrap Unterklasse ist, aber man konnte eine „[“ und „]“ an den Rändern der Taste, wickeln Sie es in ein LineBox hinzuzufügen, usw. Wenn all dies überflüssig ist, können Sie einfach die Ereignisbehandlungsfunktionen in die Klasse ButtonLabel verschieben und beim Klicken ein Signal ausgeben lassen.

Um die Taste rückgängig zu machen, wenn der Benutzer bewegt sich auf sie, es in AttrMap wickeln und die focus_map zu einem gewissen Paletteneintrag („button_reversed“, in meinem Fall) gesetzt.

0

Nach dem Vorbild des Drunken Master-Antwort, aber mit „minimal-invasiver Chirurgie“:

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) 

Hier haben wir nur das Aussehen der Taste ändern, aber sonst ihr Verhalten unverändert lassen.