当前位置:   article > 正文

Python tkinter Treeview 目录结构示例_python使用treeview树节点展开和折叠样式

python使用treeview树节点展开和折叠样式
  1. from tkinter import *
  2. from tkinter import ttk # 下拉菜单控件在ttk中
  3. import tkinter.messagebox # 弹出提示对话框
  4. import tkinter.simpledialog # 弹出对话框,获取用户输入
  5. import os
  6. top = Tk() # 初始化Tk()
  7. top.title('TEST') # 设置标题
  8. 窗口宽 = 900
  9. 窗口高 = 600
  10. # 获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
  11. 屏幕宽 = top.winfo_screenwidth()
  12. 屏幕高 = top.winfo_screenheight()
  13. 主窗口显示位置 = '%dx%d+%d+%d' % (窗口宽, 窗口高, (屏幕宽-窗口宽)/2, (屏幕高-窗口高)/2)
  14. top.geometry(主窗口显示位置)
  15. top.resizable(width=True, height=True) # 设置窗口是否可变长、宽(True:可变,False:不可变)
  16. top.grid_columnconfigure(1, weight=1) # (第1列, 自适应窗口宽)
  17. 左框 = LabelFrame(top, text='左')
  18. 右框 = LabelFrame(top, text='右')
  19. 左框.grid(row=0,column=0,sticky='NSEW')
  20. 右框.grid(row=0,column=1,sticky='NSEW')
  21. 选中_TV_IID = StringVar() # 保存变量,方便作为参数使用
  22. 根目录 = 'E:\\DATA_CACHE'
  23. def 查目录(PATH_DIR):
  24. L = os.listdir(PATH_DIR)
  25. return(L)
  26. def 读文件(PATH_FILE):
  27. f = open(PATH_FILE, 'r')
  28. S = f.read()
  29. f.close()
  30. return(S)
  31. def TV在指定节点添加子项(父级IID, L_DATA):
  32. 显示text, 类型, 本级值 = L_DATA
  33. 本级IID = Treeview_结构.insert(父级IID, END, text=显示text, values=[类型, 父级IID, 本级值])
  34. print(f" 本级IID={本级IID} 父级IID={父级IID} OBJ: {本级IID} = Treeview_结构.insert({父级IID}, END, text={显示text}, values={[类型, 父级IID, 本级值]})")
  35. def DEF_打开根():
  36. PATH_DIR = 根目录
  37. 顶级IID = Treeview_结构.insert('', END, text=PATH_DIR, values=['目录', '', PATH_DIR]) # 在根节点插入子节点(作为顶级顶点) # 指定插入位置,0表示在头部插入,END表示在尾部插入。
  38. print(f"顶级IID={顶级IID} Treeview_结构.insert('', END, text={PATH_DIR}, values={['目录', '', PATH_DIR]})")
  39. Treeview_结构.item(顶级IID, open=True) # 设置展开
  40. 选中_TV_IID.set(顶级IID)
  41. DEF_打开目录()
  42. def DEF_打开目录():
  43. 选中IID = 选中_TV_IID.get()
  44. if 选中IID:
  45. Treeview_结构.selection_set(选中IID)
  46. 选中名 = Treeview_结构.item(选中IID)["text"]
  47. 类型, 父级IID, 本级值 = Treeview_结构.item(选中IID)['values']
  48. PATH_DIR = 本级值
  49. L = 查目录(PATH_DIR)
  50. if L == []:
  51. print(f"DEF_打开 PATH_DIR={PATH_DIR} 为 []")
  52. else:
  53. for i in L:
  54. PATH = os.path.join(本级值, i)
  55. if os.path.isdir(PATH):
  56. L_DATA = [i, '目录', PATH]
  57. elif os.path.isfile(PATH):
  58. L_DATA = [i, '文件', PATH]
  59. else:
  60. L_DATA = [i, '未知', PATH]
  61. TV在指定节点添加子项(选中IID, L_DATA)
  62. DEF_TV_展开()
  63. def DEF_打开文件():
  64. 选中IID = 选中_TV_IID.get()
  65. if 选中IID:
  66. Treeview_结构.selection_set(选中IID)
  67. 选中名 = Treeview_结构.item(选中IID)["text"]
  68. 类型, 父级IID, 本级值 = Treeview_结构.item(选中IID)['values']
  69. PATH_FILE = f"{本级值}"
  70. 内容 = 读文件(PATH_FILE)
  71. print(f" DEF_打开文件 PATH_FILE={PATH_FILE} 选中IID={选中IID}({类型, 父级IID, 本级值}) 内容={内容}")
  72. def DEF_TV_展开():
  73. 选中IID = 选中_TV_IID.get()
  74. try:
  75. if Treeview_结构.item(选中IID)['open'] == 0: # 判断未展开
  76. Treeview_结构.item(选中IID, open=True) # 设置展开
  77. print(f"展开目录 {选中IID} 完成")
  78. except Exception as e:
  79. print(f"展开目录 {选中IID} 失败 {e}")
  80. def DEF_TV_折叠():
  81. 选中IID = 选中_TV_IID.get()
  82. try:
  83. if Treeview_结构.item(选中IID)['open'] != 0: # 判断已展开
  84. Treeview_结构.item(选中IID, open=0) # 设置折叠
  85. print(f"折叠目录 {选中IID} 完成")
  86. except Exception as e:
  87. print(f"折叠目录 {选中IID} 失败 {e}")
  88. def DEF_右键菜单_刷新全部():
  89. items = Treeview_结构.get_children()
  90. [Treeview_结构.delete(item) for item in items]
  91. DEF_打开根()
  92. def DEF_刷新子项():
  93. 选中IID = 选中_TV_IID.get()
  94. items = Treeview_结构.get_children(选中IID)
  95. print(f"DEF_刷新子项 选中IID={选中IID} 子IID={items}")
  96. [Treeview_结构.delete(item) for item in items]
  97. DEF_打开目录()
  98. def DEF_删除():
  99. 选中IID = 选中_TV_IID.get()
  100. Treeview_结构.selection_set(选中IID)
  101. 类型, 父级IID, 本级值 = Treeview_结构.item(选中IID)['values']
  102. PATH = 本级值
  103. if 类型 == '文件':
  104. try:
  105. os.unlink(PATH)
  106. except Exception as e:
  107. ERROR = f"删除 文件 {PATH} 失败 {e}"
  108. tkinter.messagebox.showerror(title='ERROR', message=ERROR)
  109. else:
  110. 选中_TV_IID.set(父级IID)
  111. DEF_刷新子项()
  112. elif 类型 == '目录':
  113. try:
  114. os.rmdir(PATH)
  115. except Exception as e:
  116. ERROR = f"删除 目录 {PATH} 失败 {e}"
  117. tkinter.messagebox.showerror(title='ERROR', message=ERROR)
  118. else:
  119. 选中_TV_IID.set(父级IID)
  120. DEF_刷新子项()
  121. def DEF_新建文件():
  122. 新建文件名 = tkinter.simpledialog.askstring(title='新建文件', prompt='新建文件名:')
  123. ## 确定为输入内容,取消为None
  124. if 新建文件名 != None:
  125. 选中IID = 选中_TV_IID.get()
  126. Treeview_结构.selection_set(选中IID)
  127. 类型, 父级IID, 本级值 = Treeview_结构.item(选中IID)['values']
  128. PATH = os.path.join(本级值, 新建文件名)
  129. try:
  130. f = open(PATH, 'w')
  131. f.write('测试新建文件')
  132. f.close()
  133. except Exception as e:
  134. ERROR = f"新建文件{PATH}失败{e}"
  135. tkinter.messagebox.showerror(title='ERROR', message=ERROR)
  136. else:
  137. DEF_刷新子项()
  138. def DEF_新建目录():
  139. 新建目录名 = tkinter.simpledialog.askstring(title='新建目录', prompt='新建目录名:')
  140. ## 确定为输入内容,取消为None
  141. if 新建目录名 != None:
  142. 选中IID = 选中_TV_IID.get()
  143. Treeview_结构.selection_set(选中IID)
  144. 类型, 父级IID, 本级值 = Treeview_结构.item(选中IID)['values']
  145. PATH = os.path.join(本级值, 新建目录名)
  146. try:
  147. os.makedirs(PATH)
  148. except Exception as e:
  149. ERROR = f"新建目录{PATH}失败{e}"
  150. tkinter.messagebox.showerror(title='ERROR', message=ERROR)
  151. else:
  152. DEF_刷新子项()
  153. 目录_右键菜单 = Menu(tearoff=False)
  154. 目录_右键菜单.add_command(label='打开目录', command=DEF_刷新子项)
  155. 目录_右键菜单.add_command(label='展开', command=DEF_TV_展开)
  156. 目录_右键菜单.add_command(label='折叠', command=DEF_TV_折叠)
  157. 目录_右键菜单.add_separator()
  158. 目录_右键菜单.add_command(label='新建文件', command=DEF_新建文件)
  159. 目录_右键菜单.add_command(label='新建目录', command=DEF_新建目录)
  160. 目录_右键菜单.add_command(label='刷新目录', command=DEF_刷新子项)
  161. 目录_右键菜单.add_separator()
  162. 目录_右键菜单.add_command(label='删除目录', command=DEF_删除)
  163. 目录_右键菜单.add_separator()
  164. 目录_右键菜单.add_command(label='刷新全部', command=DEF_右键菜单_刷新全部)
  165. 文件_右键菜单 = Menu(tearoff=False)
  166. 文件_右键菜单.add_command(label='打开文件', command=DEF_打开文件)
  167. 文件_右键菜单.add_command(label='删除文件', command=DEF_删除)
  168. 空白处_右键菜单 = Menu(tearoff=False)
  169. 空白处_右键菜单.add_command(label='空白处')
  170. def DEF_鼠标右键(event):
  171. 选中IID = Treeview_结构.identify_row(event.y)
  172. if 选中IID:
  173. 选中_TV_IID.set(选中IID)
  174. Treeview_结构.selection_set(选中IID) # 鼠标左键点击
  175. 选中名 = Treeview_结构.item(选中IID)["text"]
  176. 类型, 父级IID, 本级值 = Treeview_结构.item(选中IID)['values']
  177. print(f"DEF_鼠标右键 选中IID={选中IID} 选中名={选中名} 类型={类型} 父级IID={父级IID} 本级值={本级值}")
  178. if 类型 == '目录':
  179. 目录_右键菜单.post(event.x_root, event.y_root) # 光标位置显示菜单
  180. elif 类型 == '文件':
  181. 文件_右键菜单.post(event.x_root, event.y_root)
  182. else:
  183. print("DEF_鼠标右键 【点在树外】")
  184. 空白处_右键菜单.post(event.x_root, event.y_root)
  185. Treeview_结构 = ttk.Treeview(左框, show='tree', displaycolumns=(), height=20)
  186. #Treeview_结构.bind('<<TreeviewSelect>>', DEF_鼠标左键单击)
  187. #Treeview_结构.bind('<Double-Button-1>', DEF_鼠标左键双击)
  188. Treeview_结构.bind('<Button-3>', DEF_鼠标右键) # 打开右键菜单
  189. Scrollbar_竖 = Scrollbar(左框)
  190. Scrollbar_竖['command'] = Treeview_结构.yview
  191. Scrollbar_横 = Scrollbar(左框)
  192. Scrollbar_横['command'] = Treeview_结构.xview
  193. Scrollbar_横['orient'] = HORIZONTAL
  194. Scrollbar_竖.grid(row=0, column=1, sticky=S+W+E+N)
  195. Scrollbar_横.grid(row=1, column=0, sticky=S+W+E+N)
  196. Treeview_结构.config(xscrollcommand=Scrollbar_横.set, yscrollcommand=Scrollbar_竖.set) # 自动设置滚动条滑动幅度
  197. Treeview_结构.grid(row=0,column=0,sticky='NSEW')
  198. def DEF_ID查子项():
  199. 选中IID = 选中_TV_IID.get()
  200. items = Treeview_结构.get_children(选中IID)
  201. print(f"选中IID={选中IID} 子IID={items}")
  202. Button(右框, text='打开根目录', command=DEF_打开根).grid(row=0, column=0, sticky='NW')
  203. Entry(右框, textvariable=选中_TV_IID).grid(row=1,column=0)
  204. Button(右框, text='ID查子项', command=DEF_ID查子项).grid(row=1, column=1, sticky='NW')
  205. top.mainloop() ## 进入消息循环

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/975513
推荐阅读
相关标签
  

闽ICP备14008679号