GNU/Linux >> Znalost Linux >  >> Linux

Urwid:učiní kurzor neviditelným

Souhlasím s tím, že blikající kurzor na urwid.Button vypadá trochu chabě, takže jsem přišel s řešením, jak to skrýt. V urwid Button class je pouze podtřídou WidgetWrap obsahující SelectableIcon a dva textové widgety (odvozující "<" a "">"). Je to SelectableIcon třída, která ve výchozím nastavení nastaví pozici kurzoru na první znak štítku. Podtřídou SelectableIcon , úpravou pozice kurzoru a jejím zabalením do urwid.WidgetWrap podtřída si můžete vytvořit své vlastní tlačítko, které umí všechny triky a vestavěné Button , nebo ještě více.

Tady je to, jak to vypadá v mém projektu.

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)

Dále můžete zabalit ButtonLabel objekt spolu s dalšími objekty do WidgetWrap podtřída, která bude vaší vlastní třídou tlačítek.

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

V tomto kódu ve skutečnosti není mnoho kombinací widgetů v FixedButton WidgetWrap podtřídu, ale můžete přidat "[ “ a „] " k okrajům tlačítka, zabalte jej do LineBox atd. Pokud je toto vše zbytečné, můžete jednoduše přesunout funkce zpracování událostí do ButtonLabel třídy a přimět jej, aby po kliknutí vydal signál.

Chcete-li, aby se tlačítko obrátilo, když na něj uživatel pohne, zabalte jej do AttrMap a nastavte focus_map na nějakou položku palety ("button_reversed “, v mém případě).


urwid používá funkci curs_set, ale nikde ji nevystavuje jako metodu třídy. Někdo by mohl upravit urwid tak, aby umožňoval použití této metody; jinak neexistuje žádný spolehlivý způsob, jak to udělat.

Můžete to nahlásit jako problém.


Na základě odpovědi Drunken Master jsem vyčistil řešení, jak jen to bylo možné.

urwid.SelectableIcon je v podstatě urwid.Text pole s tímto ošklivým blikajícím kurzorem. Takže místo přepsání urwid.SelectableIcon a zabalení do urwid.WidgetWrap , vezměme urwid.Text přímo a nastavte jej tak, aby bylo možné jej vybrat a reagovat na aktivaci tlačítka/myši (inspirováno jednoduchým výukovým programem nabídky 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()

Funguje jako kouzlo:


Linux
  1. Jak opravit problém s neviditelným kurzorem myši v Ubuntu GNOME

  2. Pohybovat myší Posouvat, když je prostřední tlačítko stisknuto?

  3. Bash:Shift+šipky Udělat A,b,c,d?

  1. Linux – jak učinit proces neviditelným pro ostatní uživatele?

  2. Vytvořit statickou binární hodnotu?

  3. Jak udělat, aby tlačítko Unity Terminal otevřelo samostatný terminál?

  1. Nechat Tail -f vyjet na prasklé potrubí?

  2. Nastavit průhlednost oken v Gnome?

  3. vytvořit soubor protokolu