Kivy/Python : 根据类别列表更改 TreeView 中的子类别列表
Kivy/Python : Change Sub Category list in TreeView according Category List
我在Python(test.py)和kivy(test.kv)中写了一些代码。当我运行 test.py.然后显示测试菜单和用户 submenu.When 我点击用户,然后点击 +Add 按钮 show.When 点击 +add 然后显示两个文本框类型
我在两个(类别和名称)中都使用 TreeView 当我 select 来自类别 TextBox 的男性然后显示男性姓名 rows1 = [('Andrew'),('Daniel'), ('Ebenezer')].
如果我 select 来自类别 textBox 的任何类别,那么相同的列表 show.I 希望它根据类别进行更改。
如果我 select 来自类别的女性,则应显示 rows1 = [('Atarah'),('Abigail'),('Adriel')]
如果我 select 来自类别的狗,那么应该显示 rows1 = [('Abby'),('Flash'),('Penny')]
test.py
import kivy
kivy.require('1.9.0') # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.lang import Builder
from kivy.uix.dropdown import DropDown
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window
from kivy.uix.label import Label
Window.maximize()
from kivy.clock import Clock
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.image import AsyncImage
import os
import sys
#root.attributes("-toolwindow", 1)
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
def populate_tree_view_account_group(tree_view_account_group, parent, node):
if parent is None:
tree_node = tree_view_account_group.add_node(TreeViewLabelAccountGroup(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view_account_group.add_node(TreeViewLabelAccountGroup(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view_account_group(tree_view_account_group, tree_node, child_node)
#this is retrieve from database
rows = [(1, 'Male'), (2, 'Female'), (3, 'Dog')]
treeAccountGroup = []
for r in rows:
treeAccountGroup.append({'node_id': r[1], 'children': []})
class TreeviewAccountGroup(Popup):
treeviewAccount = ObjectProperty(None)
tv = ObjectProperty(None)
h = NumericProperty(0)
#ti = ObjectProperty()
popup = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewAccountGroup, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeAccountGroup:
populate_tree_view_account_group(self.tv, None, branch)
#self.remove_widgets()
self.treeviewAccount.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
def remove_widgets(self):
for child in [child for child in self.treeviewAccount.children]:
self.treeviewAccount.remove_widget(child)
def update(self, *args):
self.h = len([child for child in self.tv.children]) * 24
def filter(self, f):
self.treeviewAccount.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in treeAccountGroup:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view_account_group(self.tv, None, branch)
self.treeviewAccount.add_widget(self.tv)
def populate_tree_view_effect_type(tree_view_effect_type, parent, node):
if parent is None:
tree_node = tree_view_effect_type.add_node(TreeViewLabelEffectType(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view_effect_type.add_node(TreeViewLabelEffectType(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view_effect_type(tree_view_effect_type, tree_node, child_node)
# male name list fetch from database
rows_male = [('Andrew'),('Daniel'),('Ebenezer')]
#girl name list fetch from database
rows_girl = [('Atarah'),('Abigail'),('Adriel')]
#Dog name list fetch from database
rows_dog = [('Abby'),('Flash'),('Penny')]
treeEffectType = {'Male': [], 'Female': [], 'Dog': []}
for r in rows_male:
treeEffectType['Male'].append({'node_id': r, 'children': []})
for r in rows_girl:
treeEffectType['Female'].append({'node_id': r, 'children': []})
for r in rows_dog:
treeEffectType['Dog'].append({'node_id': r, 'children': []})
class TreeviewEffectType(Popup):
treeviewEffectType = ObjectProperty(None)
tv = ObjectProperty(None)
h = NumericProperty(0)
#ti = ObjectProperty()
#popupEffect = ObjectProperty()
def __init__(self, type, **kwargs):
super(TreeviewEffectType, self).__init__(**kwargs)
self.type = type
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeEffectType[self.type]:
populate_tree_view_effect_type(self.tv, None, branch)
# self.remove_widgets()
self.treeviewEffectType.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
def remove_widgets(self):
for child in [child for child in self.treeviewEffectType.children]:
self.treeviewEffectType.remove_widget(child)
def update(self, *args):
self.h = len([child for child in self.tv.children]) * 24
def filter(self, f):
self.treeviewEffectType.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in treeEffectType[self.type]:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view_effect_type(self.tv, None, branch)
self.treeviewEffectType.add_widget(self.tv)
class TreeViewLabelAccountGroup(Label, TreeViewNode):
pass
class TreeViewLabelEffectType(Label, TreeViewNode):
pass
class AccountGroupPopup(Popup):
category_label = ObjectProperty(None)
category_text = ObjectProperty(None)
name_label = ObjectProperty(None)
name_txt = ObjectProperty(None)
popupGroupAccount = ObjectProperty(None)
popupEffect = {}
groupType = ObjectProperty(None)
mode = StringProperty("")
col_data = ListProperty(["?", "?", "?", "?","?"])
index = NumericProperty(0)
popup4 = ObjectProperty(None)
popup5 = ObjectProperty(None)
primary_check_button = BooleanProperty(False)
secondary_check_button = BooleanProperty(False)
def __init__(self, obj, **kwargs):
super(AccountGroupPopup, self).__init__(**kwargs)
self.mode = obj.mode
if obj.mode == "Add":
self.col_data[0] = ''
self.col_data[1] = ''
self.col_data[2] = ''
self.col_data[3] = 'Select Category'
self.col_data[4] = 'Select Name'
self.popupEffect['Male'] = TreeviewEffectType('Male')
self.popupEffect['Male'].popup5 = self
self.popupEffect['Female'] = TreeviewEffectType('Female')
self.popupEffect['Female'].popup5 = self
self.popupEffect['Dog'] = TreeviewEffectType('Dog')
self.popupEffect['Dog'].popup5 = self
def display_primary_treeview(self, instance):
if len(instance.text) > 0:
if self.popupGroupAccount is None:
self.popupGroupAccount = TreeviewAccountGroup()
self.popupGroupAccount.popup4 = self
self.popupGroupAccount.filter(instance.text)
self.popupGroupAccount.open()
def display_effect_type(self, instance):
if len(self.category_text.text) > 0:
if self.popupEffect[self.category_text.text] is None:
self.popupEffect[self.category_text.text] = TreeviewEffectType(self.category_text.text)
self.popupEffect[self.category_text.text].popup5 = self
self.popupEffect[self.category_text.text].filter(self.category_text.text)
self.popupEffect[self.category_text.text].open()
class SelectableButtonGroupAccount(RecycleDataViewBehavior, Button):
''' Add selection support to the Button '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
rv_data_account_group = ObjectProperty(None)
start_point = NumericProperty(0)
mode = StringProperty("Update")
def __init__(self, **kwargs):
super(SelectableButtonGroupAccount, self).__init__(**kwargs)
Clock.schedule_interval(self.update, .0005)
def update(self, *args):
self.text = self.rv_data_account_group[self.index][self.key]
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableButtonGroupAccount, self).refresh_view_attrs(rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButtonGroupAccount, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
self.rv_data_account_group = rv.data
#print("selection changed to {0}".format(rv.data[1]))
def on_press(self):
popup = AccountGroupPopup(self)
popup.open()
class RVACCOUNTGROUP(BoxLayout):
def add_account_group(self):
self.mode = "Add"
popup = AccountGroupPopup(self)
popup.open()
class CustDrop(DropDown):
def __init__(self, **kwargs):
super(CustDrop, self).__init__(**kwargs)
self.select('')
class MainMenu(BoxLayout):
content_area = ObjectProperty()
rv = ObjectProperty(None)
dropdown = ObjectProperty(None)
def display_account_group(self):
self.dropdown.dismiss()
self.remove_widgets()
self.rvarea = RVACCOUNTGROUP()
self.content_area.add_widget(self.rvarea)
def remove_widgets(self):
self.content_area.clear_widgets()
def insert_update(self, obj):
print('Test')
class TacApp(App):
title = "FactEx"
def build(self):
self.root = Builder.load_file('test.kv')
return MainMenu()
if __name__ == '__main__':
TacApp().run()
test.kv
#:kivy 1.10.0
#:import CoreImage kivy.core.image.Image
#:import os os
<TreeviewAccountGroup>:
id: treeviewAccount
treeviewAccount: treeviewAccount
title: ""
pos_hint: {'x': .65, 'y': .3}
size_hint: .2,.4
#size: 800, 800
auto_dismiss: False
BoxLayout
orientation: "vertical"
ScrollView:
size_hint: 1, .9
BoxLayout:
size_hint_y: None
id: treeviewAccount
height: root.h
rooot: root
TextInput:
id: treeview
size_hint_y: .1
on_text: root.filter(self.text)
#BoxLayout:
#id: treeview
#on_press: root.select_node(self.text)
Button:
size_hint: 1, 0.1
text: "Close"
on_release: root.dismiss()
<TreeviewEffectType>:
#id: treeviewAccount
treeviewEffectType: treeviewEffectType
title: ""
pos_hint: {'x': .65, 'y': .3}
size_hint: .2,.4
#size: 800, 800
auto_dismiss: False
BoxLayout
orientation: "vertical"
ScrollView:
size_hint: 1, .9
BoxLayout:
size_hint_y: None
id: treeviewEffectType
height: root.h
rooot: root
TextInput:
id: treeview
size_hint_y: .1
on_text: root.filter(self.text)
#BoxLayout:
#id: treeview
#on_press: root.select_node(self.text)
Button:
size_hint: 1, 0.1
text: "Close"
on_release: root.dismiss()
<TreeViewLabelEffectType>:
height: 24
on_touch_down:
root.parent.parent.rooot.popup5.col_data[4] = self.text
#app.root.effect_type_txt.text = self.text
#root.parent.parent.rooot.popup5.popup.dismiss()
<TreeViewLabelAccountGroup>:
height: 24
on_touch_down:
root.parent.parent.rooot.popup4.col_data[3] = self.text
#app.root.effect_type_txt.text = self.text
#app.root.popupEffect.dismiss()
<AccountGroupPopup>:
title: ""
size_hint: None, None
size: 500, 350
auto_dismiss: False
name_label: name_label
name_txt: name_txt
category_text: category_text
BoxLayout:
orientation: "vertical"
GridLayout:
cols: 2
padding : 30, 0
row_default_height: '30dp'
size_hint: 1, .1
pos_hint: {'x': .1, 'y': .06}
GridLayout:
cols: 2
padding: 10, 10
spacing: 20, 20
#row_default_height: '30dp'
size_hint: 1, .7
pos_hint: {'x': 0, 'y':.65}
Label:
id:category_label
text: 'Category'
text_size: self.size
valign: 'middle'
TextInput:
id: category_text
text: root.col_data[3]
on_focus: root.display_primary_treeview(self)
Label:
id:name_label
text: 'Name'
text_size: self.size
valign: 'middle'
TextInput:
id: name_txt
text: root.col_data[4]
on_focus: root.display_effect_type(self)
Button:
text: 'Ok'
on_release:
#root.package_changes(name_txt.text,primary_group_txt.text,effect_type_txt.text)
app.root.insert_update(root)
root.dismiss()
Button:
text: 'Cancel'
on_release: root.dismiss()
<AccountGroup@RecycleView>:
viewclass: 'SelectableButtonGroupAccount'
SelectableRecycleGridLayout:
cols: 1
default_size: None, dp(26)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: True
touch_multiselect: True
<RVACCOUNTGROUP>:
BoxLayout:
orientation: "vertical"
Button:
size_hint: .05, .03
text: "+Add"
on_press: root.add_account_group()
<DropdownButton@Button>:
border: (0, 16, 0, 16)
text_size: self.size
valign: "middle"
padding_x: 5
size_hint_y: None
height: '30dp'
#on_release: dropdown.select('')
#on_release: app.root.test
background_color: 90 , 90, 90, 90
color: 0, 0.517, 0.705, 1
<MenuButton@Button>:
text_size: self.size
valign: "middle"
padding_x: 5
size : (80,30)
size_hint : (None, None)
background_color: 90 , 90, 90, 90
background_normal: ''
color: 0, 0.517, 0.705, 1
border: (0, 10, 0, 0)
<MainMenu>:
content_area: content_area
dropdown: dropdown
BoxLayout:
orientation: 'vertical'
#spacing : 10
BoxLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
size_hint_y: 1
MenuButton:
id: btn
text: 'Test'
size : (60,30)
on_release: dropdown.open(self)
CustDrop:
id: dropdown
auto_width: False
width: 150
DropdownButton:
text: 'User'
size_hint_y: None
height: '32dp'
# on_release: dropdown3.open(self)
on_release: root.display_account_group()
BoxLayout:
id: content_area
size_hint_y: 30
Label:
size_hint_y: 1
有人可以帮助我吗?
第一件事。你必须为不同的类别制作不同的列表
# male name list fetch from database
rows_male = [('Andrew'),('Daniel'),('Ebenezer')]
#girl name list fetch from database
rows_girl = [('Atarah'),('Abigail'),('Adriel')]
#Dog name list fetch from database
rows_dog = [('Abby'),('Flash'),('Penny')]
然后制作一个包含每棵树的字典
treeEffectType = {'Male': [], 'Female': [], 'Dog': []}
for r in rows_male:
treeEffectType['Male'].append({'node_id': r, 'children': []})
for r in rows_girl:
treeEffectType['Female'].append({'node_id': r, 'children': []})
for r in rows_dog:
treeEffectType['Dog'].append({'node_id': r, 'children': []})
然后稍微编辑一下您的 TreeViewEffectType class:
class TreeviewEffectType(Popup):
...
def __init__(self, type, **kwargs):
super(TreeviewEffectType, self).__init__(**kwargs)
self.type = type
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeEffectType[self.type]:
populate_tree_view_effect_type(self.tv, None, branch)
#self.remove_widgets()
self.treeviewEffectType.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
...
def filter(self, f):
self.treeviewEffectType.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in treeEffectType[self.type]:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view_effect_type(self.tv, None, branch)
self.treeviewEffectType.add_widget(self.tv)
我们将需要第一个文本输入的值,因此您必须将 属性 保存在 kv:
...
<AccountGroupPopup>:
title: ""
size_hint: None, None
size: 500, 350
auto_dismiss: False
name_label: name_label
name_txt: name_txt
category_text: category_text
...
最后编辑您的 AccountGroupPopup:
...
class AccountGroupPopup(Popup):
category_label = ObjectProperty(None)
category_text = ObjectProperty(None)
name_label = ObjectProperty(None)
name_txt = ObjectProperty(None)
popupGroupAccount = ObjectProperty(None)
popupEffect = {}
...
def __init__(self, obj, **kwargs):
super(AccountGroupPopup, self).__init__(**kwargs)
self.mode = obj.mode
if obj.mode == "Add":
self.col_data[0] = ''
self.col_data[1] = ''
self.col_data[2] = ''
self.col_data[3] = 'Select Category'
self.col_data[4] = 'Select Name'
self.popupEffect['Male'] = TreeviewEffectType('Male')
self.popupEffect['Male'].popup5 = self
self.popupEffect['Female'] = TreeviewEffectType('Female')
self.popupEffect['Female'].popup5 = self
self.popupEffect['Dog'] = TreeviewEffectType('Dog')
self.popupEffect['Dog'].popup5 = self
...
def display_effect_type(self, instance):
if len(self.category_text.text) > 0:
if self.popupEffect[self.category_text.text] is None:
self.popupEffect[self.category_text.text] = TreeviewEffectType(self.category_text.text)
self.popupEffect[self.category_text.text].popup5 = self
self.popupEffect[self.category_text.text].filter(instance.text)
self.popupEffect[self.category_text.text].open()
我在Python(test.py)和kivy(test.kv)中写了一些代码。当我运行 test.py.然后显示测试菜单和用户 submenu.When 我点击用户,然后点击 +Add 按钮 show.When 点击 +add 然后显示两个文本框类型
我在两个(类别和名称)中都使用 TreeView 当我 select 来自类别 TextBox 的男性然后显示男性姓名 rows1 = [('Andrew'),('Daniel'), ('Ebenezer')].
如果我 select 来自类别 textBox 的任何类别,那么相同的列表 show.I 希望它根据类别进行更改。
如果我 select 来自类别的女性,则应显示 rows1 = [('Atarah'),('Abigail'),('Adriel')]
如果我 select 来自类别的狗,那么应该显示 rows1 = [('Abby'),('Flash'),('Penny')]
test.py
import kivy
kivy.require('1.9.0') # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
from kivy.lang import Builder
from kivy.uix.dropdown import DropDown
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window
from kivy.uix.label import Label
Window.maximize()
from kivy.clock import Clock
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.image import AsyncImage
import os
import sys
#root.attributes("-toolwindow", 1)
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
def populate_tree_view_account_group(tree_view_account_group, parent, node):
if parent is None:
tree_node = tree_view_account_group.add_node(TreeViewLabelAccountGroup(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view_account_group.add_node(TreeViewLabelAccountGroup(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view_account_group(tree_view_account_group, tree_node, child_node)
#this is retrieve from database
rows = [(1, 'Male'), (2, 'Female'), (3, 'Dog')]
treeAccountGroup = []
for r in rows:
treeAccountGroup.append({'node_id': r[1], 'children': []})
class TreeviewAccountGroup(Popup):
treeviewAccount = ObjectProperty(None)
tv = ObjectProperty(None)
h = NumericProperty(0)
#ti = ObjectProperty()
popup = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewAccountGroup, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeAccountGroup:
populate_tree_view_account_group(self.tv, None, branch)
#self.remove_widgets()
self.treeviewAccount.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
def remove_widgets(self):
for child in [child for child in self.treeviewAccount.children]:
self.treeviewAccount.remove_widget(child)
def update(self, *args):
self.h = len([child for child in self.tv.children]) * 24
def filter(self, f):
self.treeviewAccount.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in treeAccountGroup:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view_account_group(self.tv, None, branch)
self.treeviewAccount.add_widget(self.tv)
def populate_tree_view_effect_type(tree_view_effect_type, parent, node):
if parent is None:
tree_node = tree_view_effect_type.add_node(TreeViewLabelEffectType(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view_effect_type.add_node(TreeViewLabelEffectType(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view_effect_type(tree_view_effect_type, tree_node, child_node)
# male name list fetch from database
rows_male = [('Andrew'),('Daniel'),('Ebenezer')]
#girl name list fetch from database
rows_girl = [('Atarah'),('Abigail'),('Adriel')]
#Dog name list fetch from database
rows_dog = [('Abby'),('Flash'),('Penny')]
treeEffectType = {'Male': [], 'Female': [], 'Dog': []}
for r in rows_male:
treeEffectType['Male'].append({'node_id': r, 'children': []})
for r in rows_girl:
treeEffectType['Female'].append({'node_id': r, 'children': []})
for r in rows_dog:
treeEffectType['Dog'].append({'node_id': r, 'children': []})
class TreeviewEffectType(Popup):
treeviewEffectType = ObjectProperty(None)
tv = ObjectProperty(None)
h = NumericProperty(0)
#ti = ObjectProperty()
#popupEffect = ObjectProperty()
def __init__(self, type, **kwargs):
super(TreeviewEffectType, self).__init__(**kwargs)
self.type = type
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeEffectType[self.type]:
populate_tree_view_effect_type(self.tv, None, branch)
# self.remove_widgets()
self.treeviewEffectType.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
def remove_widgets(self):
for child in [child for child in self.treeviewEffectType.children]:
self.treeviewEffectType.remove_widget(child)
def update(self, *args):
self.h = len([child for child in self.tv.children]) * 24
def filter(self, f):
self.treeviewEffectType.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in treeEffectType[self.type]:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view_effect_type(self.tv, None, branch)
self.treeviewEffectType.add_widget(self.tv)
class TreeViewLabelAccountGroup(Label, TreeViewNode):
pass
class TreeViewLabelEffectType(Label, TreeViewNode):
pass
class AccountGroupPopup(Popup):
category_label = ObjectProperty(None)
category_text = ObjectProperty(None)
name_label = ObjectProperty(None)
name_txt = ObjectProperty(None)
popupGroupAccount = ObjectProperty(None)
popupEffect = {}
groupType = ObjectProperty(None)
mode = StringProperty("")
col_data = ListProperty(["?", "?", "?", "?","?"])
index = NumericProperty(0)
popup4 = ObjectProperty(None)
popup5 = ObjectProperty(None)
primary_check_button = BooleanProperty(False)
secondary_check_button = BooleanProperty(False)
def __init__(self, obj, **kwargs):
super(AccountGroupPopup, self).__init__(**kwargs)
self.mode = obj.mode
if obj.mode == "Add":
self.col_data[0] = ''
self.col_data[1] = ''
self.col_data[2] = ''
self.col_data[3] = 'Select Category'
self.col_data[4] = 'Select Name'
self.popupEffect['Male'] = TreeviewEffectType('Male')
self.popupEffect['Male'].popup5 = self
self.popupEffect['Female'] = TreeviewEffectType('Female')
self.popupEffect['Female'].popup5 = self
self.popupEffect['Dog'] = TreeviewEffectType('Dog')
self.popupEffect['Dog'].popup5 = self
def display_primary_treeview(self, instance):
if len(instance.text) > 0:
if self.popupGroupAccount is None:
self.popupGroupAccount = TreeviewAccountGroup()
self.popupGroupAccount.popup4 = self
self.popupGroupAccount.filter(instance.text)
self.popupGroupAccount.open()
def display_effect_type(self, instance):
if len(self.category_text.text) > 0:
if self.popupEffect[self.category_text.text] is None:
self.popupEffect[self.category_text.text] = TreeviewEffectType(self.category_text.text)
self.popupEffect[self.category_text.text].popup5 = self
self.popupEffect[self.category_text.text].filter(self.category_text.text)
self.popupEffect[self.category_text.text].open()
class SelectableButtonGroupAccount(RecycleDataViewBehavior, Button):
''' Add selection support to the Button '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
rv_data_account_group = ObjectProperty(None)
start_point = NumericProperty(0)
mode = StringProperty("Update")
def __init__(self, **kwargs):
super(SelectableButtonGroupAccount, self).__init__(**kwargs)
Clock.schedule_interval(self.update, .0005)
def update(self, *args):
self.text = self.rv_data_account_group[self.index][self.key]
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableButtonGroupAccount, self).refresh_view_attrs(rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButtonGroupAccount, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
self.rv_data_account_group = rv.data
#print("selection changed to {0}".format(rv.data[1]))
def on_press(self):
popup = AccountGroupPopup(self)
popup.open()
class RVACCOUNTGROUP(BoxLayout):
def add_account_group(self):
self.mode = "Add"
popup = AccountGroupPopup(self)
popup.open()
class CustDrop(DropDown):
def __init__(self, **kwargs):
super(CustDrop, self).__init__(**kwargs)
self.select('')
class MainMenu(BoxLayout):
content_area = ObjectProperty()
rv = ObjectProperty(None)
dropdown = ObjectProperty(None)
def display_account_group(self):
self.dropdown.dismiss()
self.remove_widgets()
self.rvarea = RVACCOUNTGROUP()
self.content_area.add_widget(self.rvarea)
def remove_widgets(self):
self.content_area.clear_widgets()
def insert_update(self, obj):
print('Test')
class TacApp(App):
title = "FactEx"
def build(self):
self.root = Builder.load_file('test.kv')
return MainMenu()
if __name__ == '__main__':
TacApp().run()
test.kv
#:kivy 1.10.0
#:import CoreImage kivy.core.image.Image
#:import os os
<TreeviewAccountGroup>:
id: treeviewAccount
treeviewAccount: treeviewAccount
title: ""
pos_hint: {'x': .65, 'y': .3}
size_hint: .2,.4
#size: 800, 800
auto_dismiss: False
BoxLayout
orientation: "vertical"
ScrollView:
size_hint: 1, .9
BoxLayout:
size_hint_y: None
id: treeviewAccount
height: root.h
rooot: root
TextInput:
id: treeview
size_hint_y: .1
on_text: root.filter(self.text)
#BoxLayout:
#id: treeview
#on_press: root.select_node(self.text)
Button:
size_hint: 1, 0.1
text: "Close"
on_release: root.dismiss()
<TreeviewEffectType>:
#id: treeviewAccount
treeviewEffectType: treeviewEffectType
title: ""
pos_hint: {'x': .65, 'y': .3}
size_hint: .2,.4
#size: 800, 800
auto_dismiss: False
BoxLayout
orientation: "vertical"
ScrollView:
size_hint: 1, .9
BoxLayout:
size_hint_y: None
id: treeviewEffectType
height: root.h
rooot: root
TextInput:
id: treeview
size_hint_y: .1
on_text: root.filter(self.text)
#BoxLayout:
#id: treeview
#on_press: root.select_node(self.text)
Button:
size_hint: 1, 0.1
text: "Close"
on_release: root.dismiss()
<TreeViewLabelEffectType>:
height: 24
on_touch_down:
root.parent.parent.rooot.popup5.col_data[4] = self.text
#app.root.effect_type_txt.text = self.text
#root.parent.parent.rooot.popup5.popup.dismiss()
<TreeViewLabelAccountGroup>:
height: 24
on_touch_down:
root.parent.parent.rooot.popup4.col_data[3] = self.text
#app.root.effect_type_txt.text = self.text
#app.root.popupEffect.dismiss()
<AccountGroupPopup>:
title: ""
size_hint: None, None
size: 500, 350
auto_dismiss: False
name_label: name_label
name_txt: name_txt
category_text: category_text
BoxLayout:
orientation: "vertical"
GridLayout:
cols: 2
padding : 30, 0
row_default_height: '30dp'
size_hint: 1, .1
pos_hint: {'x': .1, 'y': .06}
GridLayout:
cols: 2
padding: 10, 10
spacing: 20, 20
#row_default_height: '30dp'
size_hint: 1, .7
pos_hint: {'x': 0, 'y':.65}
Label:
id:category_label
text: 'Category'
text_size: self.size
valign: 'middle'
TextInput:
id: category_text
text: root.col_data[3]
on_focus: root.display_primary_treeview(self)
Label:
id:name_label
text: 'Name'
text_size: self.size
valign: 'middle'
TextInput:
id: name_txt
text: root.col_data[4]
on_focus: root.display_effect_type(self)
Button:
text: 'Ok'
on_release:
#root.package_changes(name_txt.text,primary_group_txt.text,effect_type_txt.text)
app.root.insert_update(root)
root.dismiss()
Button:
text: 'Cancel'
on_release: root.dismiss()
<AccountGroup@RecycleView>:
viewclass: 'SelectableButtonGroupAccount'
SelectableRecycleGridLayout:
cols: 1
default_size: None, dp(26)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: True
touch_multiselect: True
<RVACCOUNTGROUP>:
BoxLayout:
orientation: "vertical"
Button:
size_hint: .05, .03
text: "+Add"
on_press: root.add_account_group()
<DropdownButton@Button>:
border: (0, 16, 0, 16)
text_size: self.size
valign: "middle"
padding_x: 5
size_hint_y: None
height: '30dp'
#on_release: dropdown.select('')
#on_release: app.root.test
background_color: 90 , 90, 90, 90
color: 0, 0.517, 0.705, 1
<MenuButton@Button>:
text_size: self.size
valign: "middle"
padding_x: 5
size : (80,30)
size_hint : (None, None)
background_color: 90 , 90, 90, 90
background_normal: ''
color: 0, 0.517, 0.705, 1
border: (0, 10, 0, 0)
<MainMenu>:
content_area: content_area
dropdown: dropdown
BoxLayout:
orientation: 'vertical'
#spacing : 10
BoxLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
size_hint_y: 1
MenuButton:
id: btn
text: 'Test'
size : (60,30)
on_release: dropdown.open(self)
CustDrop:
id: dropdown
auto_width: False
width: 150
DropdownButton:
text: 'User'
size_hint_y: None
height: '32dp'
# on_release: dropdown3.open(self)
on_release: root.display_account_group()
BoxLayout:
id: content_area
size_hint_y: 30
Label:
size_hint_y: 1
有人可以帮助我吗?
第一件事。你必须为不同的类别制作不同的列表
# male name list fetch from database
rows_male = [('Andrew'),('Daniel'),('Ebenezer')]
#girl name list fetch from database
rows_girl = [('Atarah'),('Abigail'),('Adriel')]
#Dog name list fetch from database
rows_dog = [('Abby'),('Flash'),('Penny')]
然后制作一个包含每棵树的字典
treeEffectType = {'Male': [], 'Female': [], 'Dog': []}
for r in rows_male:
treeEffectType['Male'].append({'node_id': r, 'children': []})
for r in rows_girl:
treeEffectType['Female'].append({'node_id': r, 'children': []})
for r in rows_dog:
treeEffectType['Dog'].append({'node_id': r, 'children': []})
然后稍微编辑一下您的 TreeViewEffectType class:
class TreeviewEffectType(Popup):
...
def __init__(self, type, **kwargs):
super(TreeviewEffectType, self).__init__(**kwargs)
self.type = type
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeEffectType[self.type]:
populate_tree_view_effect_type(self.tv, None, branch)
#self.remove_widgets()
self.treeviewEffectType.add_widget(self.tv)
Clock.schedule_once(self.update, 1)
...
def filter(self, f):
self.treeviewEffectType.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in treeEffectType[self.type]:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view_effect_type(self.tv, None, branch)
self.treeviewEffectType.add_widget(self.tv)
我们将需要第一个文本输入的值,因此您必须将 属性 保存在 kv:
...
<AccountGroupPopup>:
title: ""
size_hint: None, None
size: 500, 350
auto_dismiss: False
name_label: name_label
name_txt: name_txt
category_text: category_text
...
最后编辑您的 AccountGroupPopup:
...
class AccountGroupPopup(Popup):
category_label = ObjectProperty(None)
category_text = ObjectProperty(None)
name_label = ObjectProperty(None)
name_txt = ObjectProperty(None)
popupGroupAccount = ObjectProperty(None)
popupEffect = {}
...
def __init__(self, obj, **kwargs):
super(AccountGroupPopup, self).__init__(**kwargs)
self.mode = obj.mode
if obj.mode == "Add":
self.col_data[0] = ''
self.col_data[1] = ''
self.col_data[2] = ''
self.col_data[3] = 'Select Category'
self.col_data[4] = 'Select Name'
self.popupEffect['Male'] = TreeviewEffectType('Male')
self.popupEffect['Male'].popup5 = self
self.popupEffect['Female'] = TreeviewEffectType('Female')
self.popupEffect['Female'].popup5 = self
self.popupEffect['Dog'] = TreeviewEffectType('Dog')
self.popupEffect['Dog'].popup5 = self
...
def display_effect_type(self, instance):
if len(self.category_text.text) > 0:
if self.popupEffect[self.category_text.text] is None:
self.popupEffect[self.category_text.text] = TreeviewEffectType(self.category_text.text)
self.popupEffect[self.category_text.text].popup5 = self
self.popupEffect[self.category_text.text].filter(instance.text)
self.popupEffect[self.category_text.text].open()