首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >urwid列表框不会滚动

urwid列表框不会滚动
EN

Stack Overflow用户
提问于 2013-10-18 10:00:31
回答 1查看 1.8K关注 0票数 3
代码语言:javascript
复制
import urwid

palette = [('header', 'white', 'black'),
('reveal focus', 'black', 'dark cyan', 'standout'),]
content = urwid.SimpleListWalker([
        urwid.AttrMap(w, None, 'reveal focus') for w in [
            urwid.Text("This is a text string that is fairly long"),
            urwid.Divider("-"),
            urwid.Text("Short one"),
            urwid.Text("Another"),
            urwid.Divider("-"),
            urwid.Text("What could be after this?"),
            urwid.Text("The end."),]
    ])

listbox = urwid.ListBox(content)
show_key = urwid.Text("", wrap='clip')
head = urwid.AttrMap(show_key, 'header')
top = urwid.Frame(listbox, head)

def show_all_input(input, raw):
    show_key.set_text("Pressed: " + " ".join([
        unicode(i) for i in input]))
    return input

def exit_on_cr(input):
    if input == 'enter':
        raise urwid.ExitMainLoop()

loop = urwid.MainLoop(top, palette, input_filter=show_all_input, unhandled_input=exit_on_cr)
loop.run()

按向上或向下应该滚动列表,但在我的例子中它没有。有什么问题吗?

编辑1

代码工作得很好,事实上,我不知道什么是可滚动列表。我以为按上或下键会选择列表中的项目,但它不会。这只是滚动你的终端,当它没有足够的空间同时显示所有的项目。您必须将终端的大小调整为非常小的大小,以了解此代码的功能。

编辑2

若要在向上或向下按压时更改焦点,必须使用一个奇怪的API。我很想看到像listbox.focus_next() / listbox.focus_previous()这样的API,但是您必须自己处理这些位置。当然,您可以创建自己的函数(或子类ListBox)来提供更好的API。

代码语言:javascript
复制
def handle_input(input):
    if input == "esc":
        raise urwid.ExitMainLoop()
    head.original_widget.set_text("key pressed: %s" % input)
    lw = listbox.body        
    if input == "up":
        # this can raise an error if we scroll past first position
        try:
            lw.set_focus(lw.get_prev(lw.get_focus()[1])[1])
        except:
            pass
    elif input == "down":
        # this can raise an error if we scroll past last position
        try: 
            lw.set_focus(lw.get_next(lw.get_focus()[1])[1])
        except:
            pass

编辑3

一个更好的API:

代码语言:javascript
复制
def urwid_test():
    """
            'black', 'dark red', 'dark green', 'brown', 'dark blue',
            'dark magenta', 'dark cyan', 'light gray', 'dark gray',
            'light red', 'light green', 'yellow', 'light blue', 
            'light magenta', 'light cyan', 'white'
    """

    class MyListBox(urwid.ListBox):
        def focus_next(self):
            try: 
                self.body.set_focus(self.body.get_next(self.body.get_focus()[1])[1])
            except:
                pass
        def focus_previous(self):
            try: 
                self.body.set_focus(self.body.get_prev(self.body.get_focus()[1])[1])
            except:
                pass            

    def handle_input(input):
        if input == "esc":
            raise urwid.ExitMainLoop()
        head.original_widget.set_text("key pressed: %s" % input)
        if input == "up":
            listbox.focus_previous()
        elif input == "down":
            listbox.focus_next()
    palette = [("top","white","black"),
               ("line","light green","dark green","standout"),
               ("frame","dark magenta","white"),
               ]
    widgets = [urwid.AttrMap(widget,None,"line") for widget in
                [
                    urwid.Text("Chemma!"),
                    urwid.Divider("-"),
                    urwid.Text("Another text widget!"),
                    urwid.Divider("-"),                   
                    urwid.Text("What is your name"),
                    urwid.Divider("-"),                   
                    urwid.Text("Boy ?"),                                                            
                ]
              ]
    head    = urwid.AttrMap(urwid.Text("key pressed :",wrap="clip"),"top")
    L       = urwid.SimpleListWalker(widgets)
    listbox = MyListBox(L)
    top     = urwid.AttrMap(urwid.Frame(listbox,head),"frame")
    loop    = urwid.MainLoop(top,palette,unhandled_input=handle_input)
    loop.screen.set_terminal_properties(colors=256)
    loop.run()

if __name__ == "__main__":
    urwid_test()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-08 23:29:05

令人惊讶的是,你的问题花了这么长时间才能得到答案,但问题就在这里。我追求同样的效果,并找到了这个其他问题,它是不相关的,但是显示了我们想要的代码。

长话短说,您必须使您的小部件可选,否则它们将无法获得焦点,您将无法选择它们。这里是相关的文档部分。

总之,您必须扩展Text (或任何需要选择的小部件),并将_selectable设置为True,同时实现keypress()

代码语言:javascript
复制
class SelectableText(urwid.Text):
    _selectable = True

    def keypress(self, size, key):
        return key

然后,只需将SelectableText对象的列表传递给您的SimpleListWalker,它就会神奇地工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19446840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档