如何确定urwid列表框中的可见项目数? [英] How do I determine the number of visible items in a listbox with urwid?

查看:103
本文介绍了如何确定urwid列表框中的可见项目数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一些提示,关于当我向上或向下滚动时,urwid.ListBox中的可见项列表之下还是之上还是之下.仅当最后一个可见项目之后还有剩余项目时,向下滚动"提示才应显示,而当最后一个可见项目是列表中的最后一个项目时,向下滚动"提示应消失.相反,带有向上滚动"提示.

I'd like to implement some hinting as to whether there remains items below or above the list of visible items in an urwid.ListBox when I scroll it up or down. The 'scroll down' hint should appear only when there remains items after the last visible item and it should disappear when the last, visible item is the last item in the list. The reverse applies with the 'scroll up' hint.

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

I then need to know how many visible items there is in the list. Is there a way to retrieve the number of visible items in a list box, which I suppose is equal to the height of the list box, right?

这是我要检查的内容的起点:

Here's a starting point of what I'd like to check:

# 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)时,列表框是否在框架中完全可见.

The idea is to know if the listbox is fully visible within the frame when the terminal window is shrunk or not tall enough to display everything, i.e. frame.height >= listbox.height .

推荐答案

因此,这是通过对urwid.ListBox进行子类化来实现的一种方法,我们可以添加属性all_children_visible,该属性是在我们知道小部件的大小(即在渲染或处理输入事件时).

So, here is one way of doing this by subclassing urwid.ListBox, we can add an attribute all_children_visible which is set at the times when we know the size of the widget (that is, when rendering or when handling an input event).

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

The sample code, based on the sample you provided:

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

我不确定这种方法的性能如何(我还没有对其进行广泛的测试),所以我很好奇这种方法在您的情况下的效果-让我知道它的运行情况. :)

I'm not sure how well this performs (I haven't tested it extensively), so I'm curious how this will perform for your case -- let me know how it goes. :)

这篇关于如何确定urwid列表框中的可见项目数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆