1
+ import sys
2
+ import os
3
+ from PyQt5 .QtWidgets import (
4
+ QApplication , QMainWindow , QWidget , QVBoxLayout , QHBoxLayout ,
5
+ QLabel , QLineEdit , QCheckBox , QPushButton , QFileDialog
6
+ )
7
+ from PyQt5 .QtGui import QFontDatabase , QFont , QIcon
8
+ from PyQt5 .QtCore import Qt
9
+
10
+ class ProjectExportTool (QMainWindow ):
11
+ def __init__ (self ):
12
+ super ().__init__ ()
13
+ self .setWindowTitle ("项目文件导出工具" )
14
+ self .setGeometry (100 , 100 , 500 , 400 ) # 调整窗口大小
15
+ self .initUI ()
16
+
17
+ def initUI (self ):
18
+ self .central_widget = QWidget ()
19
+ self .setCentralWidget (self .central_widget )
20
+ self .layout = QVBoxLayout (self .central_widget )
21
+
22
+ # 加载图标
23
+ icon_path = os .path .join (os .path .dirname (__file__ ), 'icon-3种尺寸.ico' )
24
+ if os .path .exists (icon_path ):
25
+ self .setWindowIcon (QIcon (icon_path ))
26
+ else :
27
+ print ("图标文件未找到" )
28
+
29
+ # 加载并设置字体
30
+ font_path = os .path .join (os .path .dirname (__file__ ), 'HarmonyOS_Sans_SC_Regular.ttf' )
31
+ font_id = QFontDatabase .addApplicationFont (font_path )
32
+ if font_id != - 1 :
33
+ font_family = QFontDatabase .applicationFontFamilies (font_id )[0 ]
34
+ font = QFont (font_family , 12 ) # 增加基础字体大小
35
+ self .setFont (font )
36
+ else :
37
+ print ("字体加载失败,使用系统默认字体" )
38
+
39
+ # 创建标题
40
+ title_label = QLabel ("项目文件导出工具" , self )
41
+ title_label .setAlignment (Qt .AlignCenter )
42
+ title_label .setStyleSheet ("font-size: 24px; font-weight: bold; margin: 15px 0;" )
43
+ self .layout .addWidget (title_label )
44
+
45
+ # 创建拖拽框
46
+ self .drag_label = QLabel ("拖入项目文件夹" , self )
47
+ self .drag_label .setAlignment (Qt .AlignCenter )
48
+ self .drag_label .setStyleSheet ("""
49
+ QLabel {
50
+ border: 2px dashed #aaa;
51
+ border-radius: 5px;
52
+ padding: 30px;
53
+ background-color: #f8f8f8;
54
+ color: #555;
55
+ font-size: 16px;
56
+ }
57
+ """ )
58
+ self .drag_label .setMinimumHeight (120 )
59
+ self .layout .addWidget (self .drag_label )
60
+
61
+ # 创建选择文件夹按钮
62
+ self .select_button = QPushButton ("选择文件夹" , self )
63
+ self .select_button .setStyleSheet ("""
64
+ QPushButton {
65
+ background-color: #4CAF50;
66
+ color: white;
67
+ padding: 10px;
68
+ border: none;
69
+ border-radius: 4px;
70
+ font-size: 16px;
71
+ }
72
+ QPushButton:hover {
73
+ background-color: #45a049;
74
+ }
75
+ """ )
76
+ self .select_button .clicked .connect (self .select_folder )
77
+ self .layout .addWidget (self .select_button )
78
+
79
+ # 创建复选框
80
+ self .export_tree_only_checkbox = QCheckBox ("只导出文件结构" , self )
81
+ self .export_tree_only_checkbox .setStyleSheet ("font-size: 14px; margin-top: 10px;" )
82
+ self .layout .addWidget (self .export_tree_only_checkbox )
83
+
84
+ # 创建状态编辑框
85
+ self .status_edit = QLineEdit (self )
86
+ self .status_edit .setReadOnly (True )
87
+ self .status_edit .setPlaceholderText ('输出状态将显示在这里' )
88
+ self .status_edit .setStyleSheet ("""
89
+ QLineEdit {
90
+ padding: 10px;
91
+ border: 1px solid #ccc;
92
+ border-radius: 4px;
93
+ background-color: #f9f9f9;
94
+ font-size: 14px;
95
+ }
96
+ """ )
97
+ self .layout .addWidget (self .status_edit )
98
+
99
+ self .central_widget .setLayout (self .layout )
100
+ self .setAcceptDrops (True )
101
+
102
+ def select_folder (self ):
103
+ dir_path = QFileDialog .getExistingDirectory (self , "选择项目文件夹" )
104
+ if dir_path :
105
+ self .process_folder (dir_path )
106
+
107
+ def dragEnterEvent (self , event ):
108
+ if event .mimeData ().hasUrls ():
109
+ event .acceptProposedAction ()
110
+
111
+ def dropEvent (self , event ):
112
+ urls = event .mimeData ().urls ()
113
+ if urls :
114
+ dir_path = urls [0 ].toLocalFile ()
115
+ self .process_folder (dir_path )
116
+
117
+ def process_folder (self , dir_path ):
118
+ if os .path .isdir (dir_path ):
119
+ self .status_edit .clear ()
120
+ project_name = os .path .basename (dir_path )
121
+ if self .export_tree_only_checkbox .isChecked ():
122
+ output_file = os .path .join (dir_path , f'{ project_name } _文件结构.txt' )
123
+ else :
124
+ output_file = os .path .join (dir_path , f'{ project_name } _文结构和内容.txt' )
125
+ self .generate_file_structure (dir_path , output_file )
126
+ self .status_edit .setText (f'导出完成:{ output_file } ' )
127
+
128
+ def generate_file_structure (self , root_dir , output_file ):
129
+ with open (output_file , 'w' , encoding = 'utf-8' ) as f :
130
+ f .write (self .get_directory_tree (root_dir , output_file ))
131
+ if not self .export_tree_only_checkbox .isChecked ():
132
+ for dirpath , _ , filenames in os .walk (root_dir ):
133
+ for filename in filenames :
134
+ filepath = os .path .join (dirpath , filename )
135
+ if filepath == output_file :
136
+ continue
137
+ normalized_path = os .path .normpath (filepath ).replace ('\\ ' , '/' )
138
+ f .write (f"\n <file path=\" { normalized_path } \" >\n " )
139
+ try :
140
+ with open (filepath , 'r' , encoding = 'utf-8' ) as file :
141
+ content = file .read ()
142
+ f .write (content + "\n " )
143
+ except Exception as e :
144
+ f .write (f"无法读取文件内容: { e } \n " )
145
+ f .write ("</file>\n " )
146
+
147
+ def get_directory_tree (self , root_dir , output_file ):
148
+ tree = []
149
+ for dirpath , dirnames , filenames in os .walk (root_dir ):
150
+ level = dirpath .replace (root_dir , '' ).count (os .sep )
151
+ indent = '│ ' * (level )
152
+ tree .append (f"{ indent } ├── { os .path .basename (dirpath )} /" )
153
+ subindent = '│ ' * (level + 1 )
154
+ for f in filenames :
155
+ if os .path .join (dirpath , f ) == output_file :
156
+ continue
157
+ tree .append (f"{ subindent } ├── { f } " )
158
+ return "\n " .join (tree ) + "\n "
159
+
160
+ if __name__ == '__main__' :
161
+ app = QApplication (sys .argv )
162
+ app .setStyle ('Fusion' )
163
+
164
+ # 设置全局字体
165
+ font_path = os .path .join (os .path .dirname (__file__ ), 'HarmonyOS_Sans_SC_Regular.ttf' )
166
+ font_id = QFontDatabase .addApplicationFont (font_path )
167
+ if font_id != - 1 :
168
+ font_family = QFontDatabase .applicationFontFamilies (font_id )[0 ]
169
+ font = QFont (font_family , 12 ) # 增加基础字体大小
170
+ app .setFont (font )
171
+
172
+ mainWin = ProjectExportTool ()
173
+ mainWin .show ()
174
+ sys .exit (app .exec_ ())
0 commit comments