Bra*_*don 18

import Tix
class View(object):
def __init__(self, root):
self.root = root
self.makeCheckList()
def makeCheckList(self):
self.cl = Tix.CheckList(self.root, browsecmd=self.selectItem)
self.cl.pack()
self.cl.hlist.add("CL1", text="checklist1")
self.cl.hlist.add("CL1.Item1", text="subitem1")
self.cl.hlist.add("CL2", text="checklist2")
self.cl.hlist.add("CL2.Item1", text="subitem1")
self.cl.setstatus("CL2", "on")
self.cl.setstatus("CL2.Item1", "on")
self.cl.setstatus("CL1", "off")
self.cl.setstatus("CL1.Item1", "off")
self.cl.autosetmode()
def selectItem(self, item):
print item, self.cl.getstatus(item)
def main():
root = Tix.Tk()
view = View(root)
root.update()
root.mainloop()
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
如果您可以使用Tix,请使用@Brandon的解决方案。如果你被困住了Ttk(就像我一样),这里有一个基于@j_4231想法的解决方案。我们可以使用 Unicode 提供的两个字符,而不是使用图像来表示复选框:
\xe2\x98\x90\xe2\x98\x92。这些字符位于项目名称之后,用于检查当前状态:treeview.item(iid, "text")[-1]是\xe2\x98\x90或\xe2\x98\x92。我们可以在单击文本时更新项目名称。
该类TtkCheckList继承了,因此可以使用 的ttk.Treeview常用参数/方法。Treeview
import tkinter as tk\nfrom tkinter import ttk\n\nBALLOT_BOX = "\\u2610"\nBALLOT_BOX_WITH_X = "\\u2612"\n\n\nclass TtkCheckList(ttk.Treeview):\n def __init__(self, master=None, width=200, clicked=None, separator='.',\n unchecked=BALLOT_BOX, checked=BALLOT_BOX_WITH_X, **kwargs):\n """\n :param width: the width of the check list\n :param clicked: the optional function if a checkbox is clicked. Takes a\n `iid` parameter.\n :param separator: the item separator (default is `'.'`)\n :param unchecked: the character for an unchecked box (default is\n "\\u2610")\n :param unchecked: the character for a checked box (default is "\\u2612")\n\n Other parameters are passed to the `TreeView`.\n """\n if "selectmode" not in kwargs:\n kwargs["selectmode"] = "none"\n if "show" not in kwargs:\n kwargs["show"] = "tree"\n ttk.Treeview.__init__(self, master, **kwargs)\n self._separator = separator\n self._unchecked = unchecked\n self._checked = checked\n self._clicked = self.toggle if clicked is None else clicked\n\n self.column('#0', width=width, stretch=tk.YES)\n self.bind("<Button-1>", self._item_click, True)\n\n def _item_click(self, event):\n assert event.widget == self\n x, y = event.x, event.y\n element = self.identify("element", x, y)\n if element == "text":\n iid = self.identify_row(y)\n self._clicked(iid)\n\n def add_item(self, item):\n """\n Add an item to the checklist. The item is the list of nodes separated\n by dots: `Item.SubItem.SubSubItem`. **This item is used as `iid` at\n the underlying `Treeview` level.**\n """\n try:\n parent_iid, text = item.rsplit(self._separator, maxsplit=1)\n except ValueError:\n parent_iid, text = "", item\n self.insert(parent_iid, index='end', iid=item,\n text=text+" "+self._unchecked, open=True)\n\n def toggle(self, iid):\n """\n Toggle the checkbox `iid`\n """\n text = self.item(iid, "text")\n checked = text[-1] == self._checked\n status = self._unchecked if checked else self._checked\n self.item(iid, text=text[:-1] + status)\n\n def checked(self, iid):\n """\n Return True if checkbox `iid` is checked\n """\n text = self.item(iid, "text")\n return text[-1] == self._checked\n\n def check(self, iid):\n """\n Check the checkbox `iid`\n """\n text = self.item(iid, "text")\n if text[-1] == self._unchecked:\n self.item(iid, text=text[:-1] + self._checked)\n\n def uncheck(self, iid):\n """\n Uncheck the checkbox `iid`\n """\n text = self.item(iid, "text")\n if text[-1] == self._checked:\n self.item(iid, text=text[:-1] + self._unchecked)\nRun Code Online (Sandbox Code Playgroud)\n这是一个例子:
\nitems = [\n 'Item',\n 'Item.SubItem1',\n 'Item.SubItem2',\n 'Item.SubItem2.SubSubItem1',\n 'Item.SubItem2.SubSubItem2',\n 'Item.SubItem2.SubSubItem3',\n 'Item.SubItem3',\n 'Item.SubItem3.SubSubItem1',\n 'Item.SubItem4'\n]\n\nroot = tk.Tk()\nroot.title('Test')\nroot.geometry('400x300')\n\ncheck_list = TtkCheckList(root, height=len(items))\n\nfor item in items:\n check_list.add_item(item)\ncheck_list.pack()\n\nroot.mainloop()\nRun Code Online (Sandbox Code Playgroud)\n您可以使用该clicked参数来定义单击某个项目时\n的新行为。例如:
def obey_ancestor(iid):\n """\n If the status of an item is toggled, the status of all its descendants\n is also set to the new status.\n """\n set_status = check_list.uncheck if check_list.checked(iid) else check_list.check\n stack = [iid]\n while stack:\n iid = stack.pop()\n set_status(iid)\n stack.extend(check_list.get_children(iid))\nRun Code Online (Sandbox Code Playgroud)\n和:
\ncheck_list = TtkCheckList(root, height=len(items),\n clicked=obey_ancestor)\nRun Code Online (Sandbox Code Playgroud)\n
我创建了一个treeview类,其复选框继承了ttk.Treeview,但复选框不是ttk.Checkbutton,而是checked,unchecked和tristate复选框的图像.
import tkinter as tk
import tkinter.ttk as ttk
class CheckboxTreeview(ttk.Treeview):
"""
Treeview widget with checkboxes left of each item.
The checkboxes are done via the image attribute of the item, so to keep
the checkbox, you cannot add an image to the item.
"""
def __init__(self, master=None, **kw):
ttk.Treeview.__init__(self, master, **kw)
# checkboxes are implemented with pictures
self.im_checked = tk.PhotoImage(file='checked.png')
self.im_unchecked = tk.PhotoImage(file='unchecked.png')
self.im_tristate = tk.PhotoImage(file='tristate.png')
self.tag_configure("unchecked", image=self.im_unchecked)
self.tag_configure("tristate", image=self.im_tristate)
self.tag_configure("checked", image=self.im_checked)
# check / uncheck boxes on click
self.bind("<Button-1>", self.box_click, True)
def insert(self, parent, index, iid=None, **kw):
""" same method as for standard treeview but add the tag 'unchecked'
automatically if no tag among ('checked', 'unchecked', 'tristate')
is given """
if not "tags" in kw:
kw["tags"] = ("unchecked",)
elif not ("unchecked" in kw["tags"] or "checked" in kw["tags"]
or "tristate" in kw["tags"]):
kw["tags"] = ("unchecked",)
ttk.Treeview.insert(self, parent, index, iid, **kw)
def check_descendant(self, item):
""" check the boxes of item's descendants """
children = self.get_children(item)
for iid in children:
self.item(iid, tags=("checked",))
self.check_descendant(iid)
def check_ancestor(self, item):
""" check the box of item and change the state of the boxes of item's
ancestors accordingly """
self.item(item, tags=("checked",))
parent = self.parent(item)
if parent:
children = self.get_children(parent)
b = ["checked" in self.item(c, "tags") for c in children]
if False in b:
# at least one box is not checked and item's box is checked
self.tristate_parent(parent)
else:
# all boxes of the children are checked
self.check_ancestor(parent)
def tristate_parent(self, item):
""" put the box of item in tristate and change the state of the boxes of
item's ancestors accordingly """
self.item(item, tags=("tristate",))
parent = self.parent(item)
if parent:
self.tristate_parent(parent)
def uncheck_descendant(self, item):
""" uncheck the boxes of item's descendant """
children = self.get_children(item)
for iid in children:
self.item(iid, tags=("unchecked",))
self.uncheck_descendant(iid)
def uncheck_ancestor(self, item):
""" uncheck the box of item and change the state of the boxes of item's
ancestors accordingly """
self.item(item, tags=("unchecked",))
parent = self.parent(item)
if parent:
children = self.get_children(parent)
b = ["unchecked" in self.item(c, "tags") for c in children]
if False in b:
# at least one box is checked and item's box is unchecked
self.tristate_parent(parent)
else:
# no box is checked
self.uncheck_ancestor(parent)
def box_click(self, event):
""" check or uncheck box when clicked """
x, y, widget = event.x, event.y, event.widget
elem = widget.identify("element", x, y)
if "image" in elem:
# a box was clicked
item = self.identify_row(y)
tags = self.item(item, "tags")
if ("unchecked" in tags) or ("tristate" in tags):
self.check_ancestor(item)
self.check_descendant(item)
else:
self.uncheck_descendant(item)
self.uncheck_ancestor(item)
if __name__ == '__main__':
root = tk.Tk()
t = CheckboxTreeview(root, show="tree")
t.pack()
t.insert("", 0, "1", text="1")
t.insert("1", "end", "11", text="1")
t.insert("1", "end", "12", text="2")
t.insert("12", "end", "121", text="1")
t.insert("12", "end", "122", text="2")
t.insert("122", "end", "1221", text="1")
t.insert("1", "end", "13", text="3")
t.insert("13", "end", "131", text="1")
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
ttkwidgets模块中CheckboxTreeview提供了改进版本.
| 归档时间: |
|
| 查看次数: |
12927 次 |
| 最近记录: |