Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用urwid确定列表框中可见项目的数量?_Python_Listbox_Urwid - Fatal编程技术网

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

Python 如何使用urwid确定列表框中可见项目的数量?,python,listbox,urwid,Python,Listbox,Urwid,我想实现一些提示,当我向上或向下滚动urwid.ListBox时,在可见项列表的下方或上方是否仍有项。“向下滚动”提示应仅在最后一个可见项之后仍有项时出现,并且在最后一个可见项是列表中的最后一项时应消失。相反的情况适用于“向上滚动”提示 然后我需要知道列表中有多少可见项。有没有一种方法可以检索列表框中可见项的数量,我认为它等于列表框的高度,对吗 以下是我想检查的一个起点: # This example is based on https://cmsdk.com/python/is-there-a

我想实现一些提示,当我向上或向下滚动
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

因此,这里有一种方法可以通过对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()

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

你能分享一个你已经尝试过的代码的小例子吗?@elias肯定。完成。随着我开始了解urwid的工作原理,我希望这个问题在ListBox类派生之前无法解决,因为除非绘制组件,否则无法确定高度。大多数(如果不是全部的话)绘图方法都涉及一个大小参数,所以我想这就是问题所在,对吧?对,ListBox有一个
calculate\u visible
方法,它需要大小,所以我想可以创建一个子类,覆盖render方法来调用它,并设置一个属性,说明是否有不可见的项。。。我一有时间就会尝试:)关于隐藏列表条目的可视化,我在中描述了一个可能的解决方案。非常感谢@elias。“重写”render()方法是否足够?从逻辑上讲,如果我没有弄错的话,它应该由其他两个基类方法调用。@Nasha可能是的,但我认为尽早设置属性会更好,这样您就可以在事件处理程序中钩住更多的逻辑,这些处理程序已经知道事情是否合适,甚至在呈现之前就决定如何处理它--例如,您可以在keypress方法中调用回调。好的,我现在明白了。我可能在我的应用程序中不需要它。@Nasha顺便说一句,你能让这个检查可见项目的东西为你工作吗?我对这个话题有些分心,但我没有把这个放出去。我会在确认后尽快发布更新。