【问题标题】:TreeView in a ScrollView in Kivy - No ScrollKivy 的 ScrollView 中的 TreeView - 无滚动
【发布时间】:2013-04-13 21:53:14
【问题描述】:

我正在开发一个 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?

【问题讨论】:

  • 你能添加 GUI 的快照吗,我正在寻找类似于你已经实现的东西

标签: python-2.7 kivy


【解决方案1】:

a) 只为一个孩子使用GridLayout,请不要。我假设它是从何时/如果您向其添加更多孩子时遗留下来的。

b) TreeView 的文档指出它具有 minimun_height 属性,该属性指示容纳其所有子项所需的最小宽度/高度。 Treeview 不会根据孩子的数量自行改变它的高度。您应该将(在这种情况下)TreeViews 高度更新为 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()

【讨论】:

    【解决方案2】:

    向 TreeView 添加高度,然后它将滚动。像这样。

    ScrollView:
                id: kr_scroll
                do_scroll_x: False
                TreeView:
                    id: trvMenu
                    root_options: { 'text': 'Home', 'font_size': 15}
                    hide_root: False
                    indent_level: 4
                    size_hint_y: None
                    height: self.parent.height*2
    

    【讨论】:

      猜你喜欢
      • 2015-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-29
      • 2014-12-28
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      相关资源
      最近更新 更多