2013-05-25 62 views
9

Hiện tại tôi đang làm việc trên một chương trình có các tệp dự án riêng và bên trong giống như các tệp con và tôi muốn biết cách sử dụng tiện ích con treeview để hiển thị tất cả các tệp phụ bên trong dự án tập tin, bất kỳ ý tưởng?Tkinter: Treeview widget

Cảm ơn trước!

+0

Dự án mã nguồn mở này có thể giúp bạn rất nhiều: https: // github.com/talcs/tals_python_task_diary – SomethingSomething

Trả lời

17

Có một example in the source code of CPython làm thế nào để điền vào một Treeview đệ quy với nội dung của một thư mục, điều này về cơ bản là như thế nào nó hoạt động (Tôi đã gỡ bỏ các ràng buộc sự kiện và bọc nó trong một lớp học để có thể đọc tốt hơn):

import os 
import tkinter as tk 
import tkinter.ttk as ttk 

class App(tk.Frame): 
    def __init__(self, master, path): 
     tk.Frame.__init__(self, master) 
     self.tree = ttk.Treeview(self) 
     ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview) 
     xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview) 
     self.tree.configure(yscroll=ysb.set, xscroll=xsb.set) 
     self.tree.heading('#0', text=path, anchor='w') 

     abspath = os.path.abspath(path) 
     root_node = self.tree.insert('', 'end', text=abspath, open=True) 
     self.process_directory(root_node, abspath) 

     self.tree.grid(row=0, column=0) 
     ysb.grid(row=0, column=1, sticky='ns') 
     xsb.grid(row=1, column=0, sticky='ew') 
     self.grid() 

    def process_directory(self, parent, path): 
     for p in os.listdir(path): 
      abspath = os.path.join(path, p) 
      isdir = os.path.isdir(abspath) 
      oid = self.tree.insert(parent, 'end', text=p, open=False) 
      if isdir: 
       self.process_directory(oid, abspath) 

root = tk.Tk() 
path_to_my_project = # ... 
app = App(root, path=path_to_my_project) 
app.mainloop() 

cập nhật: Như @ArtOfWarfare đề cập, nó có thể để cư lười biếng cây bằng cách sử dụng sự kiện <<TreeviewOpen>>. Để mô phỏng các nút kín, tôi đã sử dụng một mục con trống được lấy ra khi một thư mục được mở ra:

import os 
import tkinter as tk 
import tkinter.ttk as ttk 


class App(object): 
    def __init__(self, master, path): 
     self.nodes = dict() 
     frame = tk.Frame(master) 
     self.tree = ttk.Treeview(frame) 
     ysb = ttk.Scrollbar(frame, orient='vertical', command=self.tree.yview) 
     xsb = ttk.Scrollbar(frame, orient='horizontal', command=self.tree.xview) 
     self.tree.configure(yscroll=ysb.set, xscroll=xsb.set) 
     self.tree.heading('#0', text='Project tree', anchor='w') 

     self.tree.grid() 
     ysb.grid(row=0, column=1, sticky='ns') 
     xsb.grid(row=1, column=0, sticky='ew') 
     frame.grid() 

     abspath = os.path.abspath(path) 
     self.insert_node('', abspath, abspath) 
     self.tree.bind('<<TreeviewOpen>>', self.open_node) 

    def insert_node(self, parent, text, abspath): 
     node = self.tree.insert(parent, 'end', text=text, open=False) 
     if os.path.isdir(abspath): 
      self.nodes[node] = abspath 
      self.tree.insert(node, 'end') 

    def open_node(self, event): 
     node = self.tree.focus() 
     abspath = self.nodes.pop(node, None) 
     if abspath: 
      self.tree.delete(self.tree.get_children(node)) 
      for p in os.listdir(abspath): 
       self.insert_node(node, p, os.path.join(abspath, p)) 


if __name__ == '__main__': 
    root = tk.Tk() 
    app = App(root, path='.') 
    root.mainloop() 
+0

Giả sử rằng người hỏi đã thực sự làm bản đồ của hệ thống tập tin, đó là một giải pháp tốt. –

+0

@DonalFellows - Đây là câu trả lời hay cho dù người hỏi đang thực sự cố gắng làm gì, bởi vì nó thực sự trả lời những gì họ hỏi. Đó là chính xác những gì tôi muốn (một ví dụ về Treeview - Tôi chỉ mới bắt đầu với tk/ttk và cần xem thêm một số ví dụ trước khi tôi sẵn sàng viết các công cụ từ đầu.) – ArtOfWarfare

+0

Hơn hai năm sau, tôi có một suy nghĩ khác về điều này - nó sẽ không thực sự không hiệu quả? Bạn sẽ điền các thư mục người dùng có thể không bao giờ kết thúc mở rộng. Chắc chắn có một cách để trì hoãn việc gọi 'process_directory' cho đến khi người dùng thực sự mở nó? – ArtOfWarfare

1

Hàng hóa nhập khẩu có thể thay đổi các dòng thứ hai và thứ ba hỗ trợ Python 3.4 trở lên trong các cách thức sau đây :

import tkinter as tk 
import tkinter.ttk as ttk 

Chữ viết thường thay thế tkinter T trong Tkinter vì Python 3.4 trở lên không còn nhận dạng Tkinter; loại bỏ lỗi "tham chiếu không được công nhận".

Chỉ thị nhập đủ điều kiện trong bản phát hành Python mới hơn nghiêm ngặt hơn về ký hiệu dấu chấm xung quanh, do đó tkinter.ttk là ttk là bắt buộc và loại bỏ nhu cầu tham chiếu đầy đủ. Caveat: người ta sẽ giả định rằng nhập khẩu tk.ttk sẽ đủ, nhưng bằng cách nào đó làm tăng một lỗi tham chiếu; loại bỏ các con trỏ thừa và xử lý macro có điều kiện dẫn tôi chọn định dạng trên - có các khả năng khác, nhưng đây là hình thức dễ sử dụng nhất.

path_to_my_project = # ... đặt ra một lỗi, mà chỉ đơn thuần là giữ chỗ (vẫn còn chức năng mặc dù) và có thể được thay đổi như sau:

path_to_my_project = "" # ... 

Hãy nhớ rằng nếu chạy kịch bản trong Windows mà một chữ đường dẫn tệp bằng cách sử dụng dấu gạch chéo ngược tăng và lỗi; bạn phải thoát khỏi backslashes trong url đường dẫn tập tin với một dấu gạch chéo trước (backslashes kép) như sau:

path_to_my_project = "C:\\Users\\userName\\Desktop\\projDir" #Windows file paths 

Thoát backslashes trong đường dẫn tập tin với backslashes loại bỏ các lỗi "Unicode ký tự thoát" ở đâu "C: \ Người dùng "giải quyết để thoát khỏi nhân vật điều khiển U trong Người dùng và đây không phải là điều chúng tôi muốn ngay từ đầu. Việc tạo đường dẫn dưới dạng chuỗi sẽ không hoạt động khi các lỗi tương tự được nâng lên, do đó, điều này:

... không có hiệu quả.

Ví dụ tập lệnh (ở trên) hoạt động với những sửa đổi này đối với Python 3.4 64bit chạy trong Windows 10 64bit không có vấn đề và rất sạch sẽ & rắn.

Tôi thích nó - chạy với ít nỗ lực (cập nhật đơn giản) mà không có lỗi, cảnh báo hoặc công việc không thể giải thích xung quanh, bs và hack. Thumbs up.