1

我想实现一些提示,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.

4

1 回答 1

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()

我不确定它的性能如何(我没有对它进行广泛的测试),所以我很好奇这将如何为您的案例执行 - 让我知道它是如何进行的。:)

于 2018-02-20T10:45:14.653 回答