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顺便说一句,你能让这个检查可见项目的东西为你工作吗?我对这个话题有些分心,但我没有把这个放出去。我会在确认后尽快发布更新。