python-2.7 - Kivy 中 ScrollView 中的 TreeView - 无滚动

标签 python-2.7 kivy

我正在开发一个 kivy 应用程序,它从 sqlite3 数据库中提取数据并用它填充 TreeView。当我展开一些组时,TreeView 变得太大而无法适应我的屏幕,因此我想将其放入 ScrollView 中,这样我仍然可以向下滚动并查看已超出屏幕底部的项目。我可以让一个基本的 ScrollView 工作,但是当我将 TreeView 放入其中时,没有滚动,并且 TreeView 的顶部超出了屏幕顶部。

我已将代码精简为在没有 .kv 文件的情况下运行的问题的工作示例:

from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.treeview import TreeView, TreeViewNode
from kivy.uix.treeview import TreeViewLabel
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.button import Button

class TreeViewButton(Button, TreeViewNode):
    pass

modGroups = [u'Fruit', u'Fruit', u'Meat', u'Dairy', u'Dairy', u'Fruit']
modItems = [u'Apple', u'Pear', u'Spam', u'Egg', u'Milk', u'Banana']
modDict = dict()
modDictUnique = dict()

def populate_tree_view(tv):
    modDict = zip(modGroups, modItems)
    print modGroups
    print modItems
    for k, v in modDict:
        if k not in modDictUnique:
            modDictUnique[k] = [v]
        else:
            modDictUnique[k].append(v)
    sortedGroups = modDictUnique.keys()
    sortedGroups.sort()
    #print modItems
    #print modDictUnique
    n = tv.add_node(TreeViewLabel(text='Food', is_open=True))
    for group in sortedGroups:
        g = tv.add_node(TreeViewLabel(text='%s' % group), n)
        for item in modDictUnique[group]:
            tv.add_node(TreeViewButton(text='%s' % item), g)

class POSFMApp(App):

    def build(self):
        layout = GridLayout(cols=1, spacing=50, size_hint_y=None,width=800)
        layout.bind(minimum_height=layout.setter('height'))
        #for i in range(30):
        #    btn = Button(text=str(i), size=(480, 40),
        #                 size_hint=(None, None))
        #    layout.add_widget(btn)
        tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4, minimum_height=5000)
        populate_tree_view(tv)
        layout.add_widget(tv)
        root = ScrollView(size_hint=(None, None), size=(800, 700))
        root.center = Window.center
        root.add_widget(layout)
        return root

if __name__ == '__main__':
    POSFMApp().run()

在我的实际应用程序中,modGroups 和 modItems 是从 sqlite3 数据库填充的,但这个示例提出了问题,而不必乱搞 sqlite3。我放入(注释掉)行:

#for i in range(30):
#    btn = Button(text=str(i), size=(480, 40),
#                 size_hint=(None, None))
#    layout.add_widget(btn)

从这里kivy ScrollView example以表明如果我取消注释这些行并注释掉有关我的 TreeView 的三行

tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4, minimum_height=5000)
populate_tree_view(tv)
layout.add_widget(tv)

然后,当我使用鼠标滚轮时,我可以获得一个工作的 ScrollView,右侧有一个滚动条。

我最好的猜测是 TreeView 不会告诉 ScrollView 它的垂直长度有多长,因此 ScrollView 没有意识到它需要在 y 轴上滚动。但这只是一个猜测。

如何让 TreeView 在 ScrollView 中工作,以便我可以滚动(尤其是在 y 轴上)浏览 TreeView?

最佳答案

a) 使用 GridLayout只为了一个 child ,豌 bean 不要。我假设这是当/如果您向其中添加更多子项时剩下的。

b) TreeView 的文档声明它有 minimun_height属性,指示容纳其所有子项所需的最小宽度/高度。 Treeview不会根据 child 的数量自行改变其高度。您应该更新(在本例中)TreeView s 高度为 minimum_height ... tv.bind(minimum_height=tv.setter('height')) c) 考虑到上述几点中提供的信息,您可以这样做::

tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4)
tv.size_hint = 1, None
tv.bind(minimum_height = tv.setter('height'))
populate_tree_view(tv)
root = ScrollView(pos = (0, 0))
root.add_widget(tv)

这是包含这些更改的完整代码,因此只需将代码复制并粘贴到 .py 文件并运行即可。

from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.treeview import TreeView, TreeViewNode
from kivy.uix.treeview import TreeViewLabel
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.button import Button

class TreeViewButton(Button, TreeViewNode):
    pass

modGroups = [u'Fruit', u'Fruit', u'Meat', u'Dairy', u'Dairy', u'Fruit']
modItems = [u'Apple', u'Pear', u'Spam', u'Egg', u'Milk', u'Banana']
modDict = dict()
modDictUnique = dict()

def populate_tree_view(tv):
    modDict = zip(modGroups, modItems)
    print modGroups
    print modItems
    for k, v in modDict:
        if k not in modDictUnique:
            modDictUnique[k] = [v]
        else:
            modDictUnique[k].append(v)
    sortedGroups = modDictUnique.keys()
    sortedGroups.sort()
    #print modItems
    #print modDictUnique
    n = tv.add_node(TreeViewLabel(text='Food', is_open=True))
    for group in sortedGroups:
        g = tv.add_node(TreeViewLabel(text='%s' % group), n)
        for item in modDictUnique[group]:
            tv.add_node(TreeViewButton(text='%s' % item), g)

class POSFMApp(App):

    def build(self):
        #for i in range(30):
        #    btn = Button(text=str(i), size=(480, 40),
        #                 size_hint=(None, None))
        #    layout.add_widget(btn)
        tv = TreeView(root_options=dict(text='Tree One'), hide_root=True, indent_level=4)
        tv.size_hint = 1, None
        tv.bind(minimum_height = tv.setter('height'))
        populate_tree_view(tv)
        root = ScrollView(pos = (0, 0))
        root.add_widget(tv)
        return root

if __name__ == '__main__':
    POSFMApp().run()

关于python-2.7 - Kivy 中 ScrollView 中的 TreeView - 无滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16122664/

相关文章:

python - 使用 Kivy+Buildozer 构建 Android 应用

android - Android 上运行的 Kivy 应用程序在屏幕锁定后关闭。如何避免?

python - 将图表作为带有按钮的小部件放置在 Kivy 上

python - 当Python只接受sqlite3时如何导入MySQL?

python - json.dumps 值错误 : Extra data unable to dump json outputs

python-2.7 - 如何使用 Python (sympy) 符号求解一对非线性方程?

android - 将 GridLayout 元素移动到新行以适应 Kivy 中较小的屏幕

image - kivy:可以使用缓冲区作为图像源吗?

python - python2 和 python3 之间的舍入行为不同

python - 列表列表的浅拷贝