如何使用urwid确定列表框中的可见项目数?

时间:2018-02-11 22:23:09

标签: python listbox urwid

当我向上或向下滚动时,我想对urwid.ListBox中的可见项列表中是否仍有项目进行暗示。 '向下滚动'提示应仅在最后一个可见项目之后仍有项目时出现,并且当最后一个可见项目是列表中的最后一项时它应该消失。反向适用于向上滚动'提示。

然后我需要知道列表中有多少可见项目。有没有办法检索列表框中的可见项目数,我想这等于列表框的高度,对吧?

以下是我要检查的起点:

# This example is based on https://cmsdk.com/python/is-there-a-focus-changed-event-in-urwid.html
import urwid

def callback():
    index = str(listbox.get_focus()[1])
    debug.set_text("Index of selected item: " + index)

captions = "A B C D E F".split()
debug = urwid.Text("Debug")
items = [urwid.Button(caption) for caption in captions]
walker = urwid.SimpleListWalker(items)
listbox = urwid.ListBox(walker)
urwid.connect_signal(walker, "modified", callback)
frame = urwid.Frame(body=listbox, header=debug)
urwid.MainLoop(frame).run()

当终端窗口缩小或不足以显示所有内容时,我们的想法是知道列表框是否在框架内完全可见,即frame.height >= listbox.height

1 个答案:

答案 0 :(得分:1)

所以,这是通过子类化urwid.ListBox来实现这一目的的一种方法,我们可以添加一个属性all_children_visible,它在我们知道窗口小部件的大小时(即渲染时或何时)设置处理输入事件。)

示例代码,基于您提供的示例:

import string
import urwid

class MyListBox(urwid.ListBox):
    all_children_visible = True

    def keypress(self, size, *args, **kwargs):
        self.all_children_visible = self._compute_all_children_visible(size)
        return super(MyListBox, self).keypress(size, *args, **kwargs)

    def mouse_event(self, size, *args, **kwargs):
        self.all_children_visible = self._compute_all_children_visible(size)
        return super(MyListBox, self).mouse_event(size, *args, **kwargs)

    def render(self, size, *args, **kwargs):
        self.all_children_visible = self._compute_all_children_visible(size)
        return super(MyListBox, self).render(size, *args, **kwargs)

    def _compute_all_children_visible(self, size):
        n_total_widgets = len(self.body)
        middle, top, bottom = self.calculate_visible(size)
        n_visible = len(top[1]) + len(bottom[1])
        if middle:
            n_visible += 1
        return n_total_widgets == n_visible

def callback():
    debug.set_text(
        "Are all children visible? {}\n".format(listbox.all_children_visible)
    )


captions = list(string.uppercase + string.lowercase)

# uncomment this line to test case of all children visible:
# captions = list(string.uppercase)

debug = urwid.Text("Debug")
items = [urwid.Button(caption) for caption in captions]
walker = urwid.SimpleListWalker(items)
listbox = MyListBox(walker)
urwid.connect_signal(walker, "modified", callback)
frame = urwid.Frame(body=listbox, header=debug)
urwid.MainLoop(frame).run()

我不确定它的表现如何(我还没有广泛测试过),所以我很好奇这对你的情况会如何表现 - 让我知道它是怎么回事。 :)