在 kivy 中使用多个 treeview 小部件
use multiple treeview widgets in kivy
test.py
import sqlite3 as lite
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.label import Label
from kivy.properties import ObjectProperty,StringProperty
import sys
Window.clearcolor = (.152, .149, .149, 0)
Window.size = (700, 330)
def populate_tree_view(tree_view, parent, node):
if parent is None:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view(tree_view, tree_node, child_node)
rows = [('1','1','city1'),('2','2','city2'),('3','3','city3')]
tree = []
for r in rows:
tree.append({'node_id': r[2], 'children': []})
class TreeViewLabel(Label, TreeViewNode):
pass
class TreeviewGroup(Popup):
treeview = ObjectProperty(None)
tv = ObjectProperty(None)
#ti = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewGroup, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in tree:
populate_tree_view(self.tv, None, branch)
self.remove_widgets()
self.treeview.add_widget(self.tv)
def remove_widgets(self):
for child in [child for child in self.treeview.children]:
self.treeview.remove_widget(child)
def filter(self, f):
self.treeview.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in tree:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view(self.tv, None, branch)
self.treeview.add_widget(self.tv)
def populate_tree_view_area(tree_view, parent, node):
if parent is None:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view(tree_view, tree_node, child_node)
rows = [('1','1','area1'),('2','2','area2'),('3','3','area3')]
treeArea = []
for r in rows:
treeArea.append({'node_id': r[2], 'children': []})
class TreeviewArea(Popup):
treeviewArea = ObjectProperty(None)
tv = ObjectProperty(None)
#ti = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewArea, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeArea:
populate_tree_view_area(self.tv, None, branch)
self.remove_widgets()
self.treeviewArea.add_widget(self.tv)
def remove_widgets(self):
for child in [child for child in self.treeviewArea.children]:
self.treeviewArea.remove_widget(child)
class AreaScreen(Screen):
groupName = ObjectProperty(None)
popup = ObjectProperty(None)
#statecode = StringProperty('')
def display_cities(self, instance):
if len(instance.text) > 0:
if self.popup is None:
self.popup = TreeviewGroup()
#self.popup.filter(instance.text)
self.popup.open()
def display_areas(self, instance):
if len(instance.text) > 0:
if self.popup is None:
self.popup = TreeviewGroup()
#self.popup.filter(instance.text)
self.popup.open()
class FactArea(App):
def build(self):
self.root = Builder.load_file('test.kv')
return self.root
if __name__ == '__main__':
FactArea().run()
test.kv
:基维 1.10.0
<TreeViewLabel>:
on_touch_down:
app.root.cityName.text = self.text
#app.root.select_node(self)
app.root.popup.dismiss()
<TreeviewGroup>:
id: treeview
treeview: treeview
title: "Select City"
size_hint: None, None
size: 400, 350
auto_dismiss: False
BoxLayout
orientation: "vertical"
#TextInput:
#id: ti
#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()
<TreeviewGroupArea>:
id: treeviewArea
treeviewArea: treeviewArea
title: "Select City"
size_hint: None, None
size: 400, 350
auto_dismiss: False
BoxLayout
orientation: "vertical"
#TextInput:
#id: ti
#size_hint_y: .1
#on_text: root.filter(self.text)
BoxLayout:
id: treeviewArea
#on_press: root.select_node(self.text)
Button:
size_hint: 1, 0.1
text: "Close"
on_release: root.dismiss()
<CustomLabel@Label>:
text_size: self.size
valign: "middle"
padding_x: 5
<SingleLineTextInput@TextInput>:
multiline: False
<GreenButton@Button>:
background_color: 1, 1, 1, 1
size_hint_y: None
height: self.parent.height * 0.200
AreaScreen:
cityName: cityName
GridLayout:
cols: 2
padding : 30,30
spacing: 10, 10
row_default_height: '30dp'
Label:
text: 'City'
text_size: self.size
valign: 'middle'
padding_x: 50
SingleLineTextInput:
id: cityName
font_size_valign:self.height*0.4
on_text: root.display_cities(self)
Label:
text: 'Area'
text_size: self.size
valign: 'middle'
padding_x: 50
SingleLineTextInput:
id: areaName
on_text: root.display_areas(self)
GreenButton:
text: 'Ok'
on_press: root.insert_data(cityName.text, areaName.text)
GreenButton:
text: 'Cancel'
on_press: app.stop()
如果我在城市中输入任何内容,那么城市会显示在 treeview.But 我输入任何内容
在 area 然后还显示 city.I 已经为 area 编写了单独的函数,但我不知道出了什么问题?如果可能的话,使用相同的函数和 if else 条件用于城市树视图和 area treeview.Code 不会重复一遍,这样会更好。
I select city then value put in city TextBox 但 i select area then value also set in city TextBox.How to put value in separate TextBox?City treeView value put in city TextBox 和 Area TreeView 值放在区域 TextBox 中。
我知道你试图修改,但这还不够,你必须为每个弹出窗口重新定义 TreeView class 和 TreeViewLabel
我只会post区域弹出窗口所必需的
...
def populate_tree_view_area(tree_view, parent, node):
if parent is None:
tree_node = tree_view.add_node(TreeViewLabelArea(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view.add_node(TreeViewLabelArea(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view(tree_view, tree_node, child_node)
rowsa = [('1','1','area1'),('2','2','area2'),('3','3','area3')]
treeArea = []
for r in rowsa:
treeArea.append({'node_id': r[2], 'children': []})
class TreeViewLabelArea(Label, TreeViewNode):
pass
class TreeviewArea(Popup):
#You can let it as it is
...
class AreaScreen(Screen):
groupName = ObjectProperty(None)
popupcity = ObjectProperty(None)
popuparea = ObjectProperty(None)
#statecode = StringProperty('')
...
def display_areas(self, instance):
if len(instance.text) > 0:
if self.popuparea is None:
self.popuparea = TreeviewArea()
#self.popup.filter(instance.text)
self.popuparea.open()
然后在您的 kv 中将 TreaviewGroupArea 替换为 main 中定义的 TreeViewArea 并添加 TreeViewLabelArea 规则
...
<TreeViewLabelArea>:
height: 24
on_touch_down:
app.root.areaName.text = self.text
#app.root.select_node(self)
app.root.popuparea.dismiss()
最后在 AreaScreen 规则中添加 areaName 属性
...
AreaScreen:
cityName: cityName
areaName: areaName
...
希望对您有所帮助
test.py
import sqlite3 as lite
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.treeview import TreeView, TreeViewLabel, TreeViewNode
from kivy.uix.label import Label
from kivy.properties import ObjectProperty,StringProperty
import sys
Window.clearcolor = (.152, .149, .149, 0)
Window.size = (700, 330)
def populate_tree_view(tree_view, parent, node):
if parent is None:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view(tree_view, tree_node, child_node)
rows = [('1','1','city1'),('2','2','city2'),('3','3','city3')]
tree = []
for r in rows:
tree.append({'node_id': r[2], 'children': []})
class TreeViewLabel(Label, TreeViewNode):
pass
class TreeviewGroup(Popup):
treeview = ObjectProperty(None)
tv = ObjectProperty(None)
#ti = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewGroup, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in tree:
populate_tree_view(self.tv, None, branch)
self.remove_widgets()
self.treeview.add_widget(self.tv)
def remove_widgets(self):
for child in [child for child in self.treeview.children]:
self.treeview.remove_widget(child)
def filter(self, f):
self.treeview.clear_widgets()
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
new_tree = []
for n in tree:
if f.lower() in n['node_id'].lower():
new_tree.append(n)
for branch in new_tree:
populate_tree_view(self.tv, None, branch)
self.treeview.add_widget(self.tv)
def populate_tree_view_area(tree_view, parent, node):
if parent is None:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view.add_node(TreeViewLabel(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view(tree_view, tree_node, child_node)
rows = [('1','1','area1'),('2','2','area2'),('3','3','area3')]
treeArea = []
for r in rows:
treeArea.append({'node_id': r[2], 'children': []})
class TreeviewArea(Popup):
treeviewArea = ObjectProperty(None)
tv = ObjectProperty(None)
#ti = ObjectProperty()
def __init__(self, **kwargs):
super(TreeviewArea, self).__init__(**kwargs)
self.tv = TreeView(root_options=dict(text=""),
hide_root=False,
indent_level=4)
for branch in treeArea:
populate_tree_view_area(self.tv, None, branch)
self.remove_widgets()
self.treeviewArea.add_widget(self.tv)
def remove_widgets(self):
for child in [child for child in self.treeviewArea.children]:
self.treeviewArea.remove_widget(child)
class AreaScreen(Screen):
groupName = ObjectProperty(None)
popup = ObjectProperty(None)
#statecode = StringProperty('')
def display_cities(self, instance):
if len(instance.text) > 0:
if self.popup is None:
self.popup = TreeviewGroup()
#self.popup.filter(instance.text)
self.popup.open()
def display_areas(self, instance):
if len(instance.text) > 0:
if self.popup is None:
self.popup = TreeviewGroup()
#self.popup.filter(instance.text)
self.popup.open()
class FactArea(App):
def build(self):
self.root = Builder.load_file('test.kv')
return self.root
if __name__ == '__main__':
FactArea().run()
test.kv
:基维 1.10.0
<TreeViewLabel>:
on_touch_down:
app.root.cityName.text = self.text
#app.root.select_node(self)
app.root.popup.dismiss()
<TreeviewGroup>:
id: treeview
treeview: treeview
title: "Select City"
size_hint: None, None
size: 400, 350
auto_dismiss: False
BoxLayout
orientation: "vertical"
#TextInput:
#id: ti
#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()
<TreeviewGroupArea>:
id: treeviewArea
treeviewArea: treeviewArea
title: "Select City"
size_hint: None, None
size: 400, 350
auto_dismiss: False
BoxLayout
orientation: "vertical"
#TextInput:
#id: ti
#size_hint_y: .1
#on_text: root.filter(self.text)
BoxLayout:
id: treeviewArea
#on_press: root.select_node(self.text)
Button:
size_hint: 1, 0.1
text: "Close"
on_release: root.dismiss()
<CustomLabel@Label>:
text_size: self.size
valign: "middle"
padding_x: 5
<SingleLineTextInput@TextInput>:
multiline: False
<GreenButton@Button>:
background_color: 1, 1, 1, 1
size_hint_y: None
height: self.parent.height * 0.200
AreaScreen:
cityName: cityName
GridLayout:
cols: 2
padding : 30,30
spacing: 10, 10
row_default_height: '30dp'
Label:
text: 'City'
text_size: self.size
valign: 'middle'
padding_x: 50
SingleLineTextInput:
id: cityName
font_size_valign:self.height*0.4
on_text: root.display_cities(self)
Label:
text: 'Area'
text_size: self.size
valign: 'middle'
padding_x: 50
SingleLineTextInput:
id: areaName
on_text: root.display_areas(self)
GreenButton:
text: 'Ok'
on_press: root.insert_data(cityName.text, areaName.text)
GreenButton:
text: 'Cancel'
on_press: app.stop()
如果我在城市中输入任何内容,那么城市会显示在 treeview.But 我输入任何内容 在 area 然后还显示 city.I 已经为 area 编写了单独的函数,但我不知道出了什么问题?如果可能的话,使用相同的函数和 if else 条件用于城市树视图和 area treeview.Code 不会重复一遍,这样会更好。
I select city then value put in city TextBox 但 i select area then value also set in city TextBox.How to put value in separate TextBox?City treeView value put in city TextBox 和 Area TreeView 值放在区域 TextBox 中。
我知道你试图修改,但这还不够,你必须为每个弹出窗口重新定义 TreeView class 和 TreeViewLabel
我只会post区域弹出窗口所必需的
...
def populate_tree_view_area(tree_view, parent, node):
if parent is None:
tree_node = tree_view.add_node(TreeViewLabelArea(text=node['node_id'],
is_open=True))
else:
tree_node = tree_view.add_node(TreeViewLabelArea(text=node['node_id'],
is_open=True), parent)
for child_node in node['children']:
populate_tree_view(tree_view, tree_node, child_node)
rowsa = [('1','1','area1'),('2','2','area2'),('3','3','area3')]
treeArea = []
for r in rowsa:
treeArea.append({'node_id': r[2], 'children': []})
class TreeViewLabelArea(Label, TreeViewNode):
pass
class TreeviewArea(Popup):
#You can let it as it is
...
class AreaScreen(Screen):
groupName = ObjectProperty(None)
popupcity = ObjectProperty(None)
popuparea = ObjectProperty(None)
#statecode = StringProperty('')
...
def display_areas(self, instance):
if len(instance.text) > 0:
if self.popuparea is None:
self.popuparea = TreeviewArea()
#self.popup.filter(instance.text)
self.popuparea.open()
然后在您的 kv 中将 TreaviewGroupArea 替换为 main 中定义的 TreeViewArea 并添加 TreeViewLabelArea 规则
...
<TreeViewLabelArea>:
height: 24
on_touch_down:
app.root.areaName.text = self.text
#app.root.select_node(self)
app.root.popuparea.dismiss()
最后在 AreaScreen 规则中添加 areaName 属性
...
AreaScreen:
cityName: cityName
areaName: areaName
...
希望对您有所帮助