Saya setuju bahwa kursor berkedip pada urwid.Button
terlihat agak timpang, jadi saya menemukan solusi untuk menyembunyikannya. Di urwid, Button
kelas hanyalah subkelas dari WidgetWrap
berisi SelectableIcon
dan dua widget Teks (terlampir "<" dan ">"). Ini adalah SelectableIcon
kelas yang mengatur posisi kursor ke karakter pertama label, secara default. Dengan mensubklasifikasikan SelectableIcon
, memodifikasi posisi kursor dan kemudian membungkusnya menjadi urwid.WidgetWrap
subclass Anda dapat membuat tombol kustom Anda sendiri yang dapat melakukan semua trik Button
bawaan , atau bahkan lebih.
Inilah tampilannya di proyek saya.
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)
Selanjutnya, Anda dapat membungkus ButtonLabel
objek bersama dengan objek lain ke dalam WidgetWrap
subkelas yang akan menjadi kelas tombol khusus Anda.
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
Pada kode ini sebenarnya tidak banyak kombinasi widget di FixedButton
WidgetWrap
subkelas, tetapi Anda dapat menambahkan "[
" dan "]
" ke tepi tombol, bungkus menjadi LineBox
, dll. Jika semua ini berlebihan, Anda dapat memindahkan fungsi penanganan kejadian ke dalam ButtonLabel
kelas, dan membuatnya memancarkan sinyal saat diklik.
Untuk membuat tombol terbalik saat pengguna memindahkannya, bungkus menjadi AttrMap
dan atur focus_map
ke beberapa entri palet ("button_reversed
", dalam kasus saya).
urwid menggunakan fungsi curs_set, tetapi tidak menampilkannya sebagai metode kelas di mana pun. Seseorang dapat memodifikasi urwid untuk mengizinkan menggunakan metode ini; jika tidak, tidak ada metode yang dapat diandalkan untuk melakukan ini.
Anda dapat melaporkannya sebagai masalah.
Berdasarkan jawaban Drunken Master, saya telah membersihkan solusinya sebanyak mungkin.
urwid.SelectableIcon
pada dasarnya adalah urwid.Text
bidang dengan kursor berkedip jelek ini. Jadi alih-alih mengganti urwid.SelectableIcon
dan mengemasnya menjadi urwid.WidgetWrap
, mari ambil urwid.Text
langsung dan membuatnya dapat dipilih dan bereaksi terhadap aktivasi tombol/mouse (terinspirasi dari tutorial menu sederhana 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()
Bekerja seperti pesona: