2011-02-24 3 views
15

저는 Tkinter와 Tix를 사용하여 작은 프로그램을 작성했습니다. 트리 뷰에서 항목을 선택할 수 있도록 체크 박스 (체크 버튼)가있는 트리보기가 필요한 시점에 있습니다. 쉬운 방법이 있나요? 나는 ttk.Treeview()를보고 있었고 트리보기를 쉽게 볼 수 있지만보기에 체크 버튼을 삽입하는 방법이 있습니까?Python의 확인란을 사용하여 트리보기를 만드는 방법

간단한 코드 스 니펫은 정말 감사하겠습니다.

나는 ttk에 국한되지 않습니다. 아무거나는 할 것이다; 한 내가 예 또는 좋은 문서를 가지고 나는 내가 ttk.Treeview을 상속 체크 박스와 트 리뷰 클래스를 만들어

답변

17

enter image description here

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() 
+2

어떻게 든 체크 박스를 기본으로 보이게하려면 ttk를 포함시킬 수 있습니까? – pihentagy

+3

Tix와 Tkinter를 사용하지 않고이 방법을 만들 수 있습니까? –

+0

파이썬 2.7이 있고 Tix가 설치되어 있지 않아 대안을 찾으려고합니다. –

5

작동 할 수 있지만, 체크 박스는 ttk.Checkbutton 만의 이미지되지 않습니다 체크, 체크되지 않은 체크 박스 및 삼중 체크 박스.

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() 

CheckboxTreeview의 개선 된 버전 ttkwidgets 모듈에서 사용할 수있다.

+0

아이디어가 좋지만 'Treeview'에 일정량의 항목이있는 경우 얼마나 잘 조절되는지 잘 모르겠습니다. 이미지가 작더라도 여전히 작은 크기의 메모리가 필요하지 않습니다. – rbaleksandar

+0

@rbaleksandar 커다란 나무에는 쓸모가 없지만, 수백 가지 항목이 없다면 Tix보다 더 좋은 나무가됩니다. –

+0

왜 이것이 확장 가능한 솔루션이 아닙니까? 이미지가 모든 treenode에 복사됩니까? 이미지 데이터의 참조 만 노드를 통해 공유 될 것으로 기대됩니다. 따라서 메모리에 2 개의 이미지 만 있습니다. 아니면 내가 틀렸어? – Hatatister

관련 문제