-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstatus_viewer.py
More file actions
263 lines (206 loc) · 10 KB
/
status_viewer.py
File metadata and controls
263 lines (206 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
"""
文件状态查看器GUI
提供图形界面来查看和管理文件的完成状态
"""
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
from pathlib import Path
from typing import List, Dict, Any
import sys
# 添加当前目录到路径
current_dir = Path(__file__).parent
sys.path.insert(0, str(current_dir))
from status_manager import StatusManager
class StatusViewer:
"""文件状态查看器GUI应用"""
def __init__(self, root):
self.root = root
self.root.title("文件完成状态管理器")
self.root.geometry("800x600")
self.manager = StatusManager()
self.current_directory = None
self.file_list = []
self._create_widgets()
self._refresh_status()
def _create_widgets(self):
"""创建GUI组件"""
# 工具栏
toolbar = ttk.Frame(self.root)
toolbar.pack(fill=tk.X, padx=5, pady=5)
ttk.Button(toolbar, text="选择目录", command=self._select_directory).pack(side=tk.LEFT, padx=2)
ttk.Button(toolbar, text="刷新", command=self._refresh_status).pack(side=tk.LEFT, padx=2)
ttk.Button(toolbar, text="清理无效记录", command=self._cleanup_missing).pack(side=tk.LEFT, padx=2)
# 目录显示
dir_frame = ttk.Frame(self.root)
dir_frame.pack(fill=tk.X, padx=5, pady=2)
ttk.Label(dir_frame, text="当前目录:").pack(side=tk.LEFT)
self.dir_label = ttk.Label(dir_frame, text="未选择", foreground="gray")
self.dir_label.pack(side=tk.LEFT, padx=5)
# 文件列表
list_frame = ttk.Frame(self.root)
list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 创建Treeview
columns = ("文件名", "状态", "修改日期")
self.tree = ttk.Treeview(list_frame, columns=columns, show="headings", selectmode="extended")
# 设置列
self.tree.heading("文件名", text="文件名")
self.tree.heading("状态", text="状态")
self.tree.heading("修改日期", text="修改日期")
self.tree.column("文件名", width=400, anchor=tk.W)
self.tree.column("状态", width=100, anchor=tk.CENTER)
self.tree.column("修改日期", width=200, anchor=tk.CENTER)
# 配置标签颜色:已完成的文件显示为红色
self.tree.tag_configure("completed", foreground="red")
# 滚动条
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)
self.tree.configure(yscrollcommand=scrollbar.set)
self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# 绑定双击事件
self.tree.bind("<Double-1>", self._toggle_selected)
# 状态栏
status_frame = ttk.Frame(self.root)
status_frame.pack(fill=tk.X, padx=5, pady=2)
self.status_label = ttk.Label(status_frame, text="就绪")
self.status_label.pack(side=tk.LEFT)
# 操作按钮
button_frame = ttk.Frame(self.root)
button_frame.pack(fill=tk.X, padx=5, pady=5)
ttk.Button(button_frame, text="切换选中项状态", command=self._toggle_selected).pack(side=tk.LEFT, padx=2)
ttk.Button(button_frame, text="标记为完成", command=lambda: self._set_selected_status(True)).pack(side=tk.LEFT, padx=2)
ttk.Button(button_frame, text="取消完成标记", command=lambda: self._set_selected_status(False)).pack(side=tk.LEFT, padx=2)
ttk.Button(button_frame, text="打开文件位置", command=self._open_file_location).pack(side=tk.LEFT, padx=2)
def _select_directory(self):
"""选择要查看的目录"""
directory = filedialog.askdirectory(title="选择目录")
if directory:
self.current_directory = directory
self.dir_label.config(text=directory, foreground="black")
self._refresh_status()
def _refresh_status(self):
"""刷新文件列表和状态"""
self.tree.delete(*self.tree.get_children())
self.file_list = []
if not self.current_directory:
# 如果没有选择目录,显示所有有状态的文件
all_statuses = self.manager.get_all_statuses()
for file_path, status in all_statuses.items():
if os.path.exists(file_path):
self._add_file_to_tree(file_path, status)
self.dir_label.config(text="显示所有有状态的文件", foreground="gray")
else:
# 显示选中目录下的所有文件
if os.path.exists(self.current_directory):
for root, dirs, files in os.walk(self.current_directory):
for file in files:
file_path = os.path.join(root, file)
status = self.manager.get_status(file_path)
self._add_file_to_tree(file_path, status)
count = len(self.file_list)
completed = sum(1 for f in self.file_list if f.get('completed', False))
self.status_label.config(text=f"共 {count} 个文件,{completed} 个已完成")
def _add_file_to_tree(self, file_path: str, status: Dict[str, Any]):
"""添加文件到树形列表"""
try:
path_obj = Path(file_path)
file_name = path_obj.name
file_dir = str(path_obj.parent)
# 状态文本
if status and status.get("completed", False):
status_text = "✓ 完成"
status_color = "green"
else:
status_text = "未完成"
status_color = "gray"
# 修改日期
try:
mod_time = os.path.getmtime(file_path)
from datetime import datetime
mod_date = datetime.fromtimestamp(mod_time).strftime("%Y-%m-%d %H:%M:%S")
except:
mod_date = "未知"
# 添加状态日期
if status and "date" in status:
status_text += f" ({status['date'][:10]})"
# 为已完成的文件设置红色标签
tags = []
if status and status.get("completed", False):
tags.append("completed")
# 插入到树形视图(已完成的文件会显示为红色)
item = self.tree.insert("", tk.END, values=(file_name, status_text, mod_date), tags=tags)
# 存储文件信息
file_info = {
'item_id': item,
'path': file_path,
'completed': status.get("completed", False) if status else False,
'directory': file_dir
}
self.file_list.append(file_info)
except Exception as e:
print(f"Error adding file {file_path}: {e}")
def _get_selected_files(self) -> List[Dict[str, Any]]:
"""获取选中的文件"""
selected_items = self.tree.selection()
selected_files = []
for item_id in selected_items:
# 在file_list中找到对应的文件
for file_info in self.file_list:
if file_info['item_id'] == item_id:
selected_files.append(file_info)
break
return selected_files
def _toggle_selected(self, event=None):
"""切换选中文件的状态"""
selected_files = self._get_selected_files()
if not selected_files:
messagebox.showwarning("警告", "请先选择文件")
return
for file_info in selected_files:
current_status = self.manager.is_completed(file_info['path'])
new_status = not current_status
# 使用带标记的方法更新状态
self.manager.set_completed_with_mark(file_info['path'], new_status)
file_info['completed'] = new_status
self._refresh_status()
messagebox.showinfo("成功", f"已切换 {len(selected_files)} 个文件的状态")
def _set_selected_status(self, completed: bool):
"""设置选中文件的状态"""
selected_files = self._get_selected_files()
if not selected_files:
messagebox.showwarning("警告", "请先选择文件")
return
for file_info in selected_files:
# 使用带标记的方法更新状态
self.manager.set_completed_with_mark(file_info['path'], completed)
file_info['completed'] = completed
self._refresh_status()
status_text = "完成" if completed else "未完成"
messagebox.showinfo("成功", f"已将 {len(selected_files)} 个文件标记为{status_text}")
def _open_file_location(self):
"""打开文件所在位置"""
selected_files = self._get_selected_files()
if not selected_files:
messagebox.showwarning("警告", "请先选择文件")
return
if len(selected_files) > 1:
messagebox.showinfo("提示", "已选择多个文件,将打开第一个文件的所在位置")
file_path = selected_files[0]['path']
directory = selected_files[0]['directory']
# 在Windows资源管理器中打开文件夹并选中文件
try:
os.system(f'explorer /select,"{file_path}"')
except Exception as e:
messagebox.showerror("错误", f"无法打开文件位置: {e}")
def _cleanup_missing(self):
"""清理不存在的文件记录"""
count = self.manager.cleanup_missing_files()
messagebox.showinfo("清理完成", f"已清理 {count} 个无效记录")
self._refresh_status()
def main():
"""主函数"""
root = tk.Tk()
app = StatusViewer(root)
root.mainloop()
if __name__ == "__main__":
main()