1- import os
1+ import os , sys
22import tkinter as tk
33from tkinter import filedialog , messagebox , ttk
44import platform
@@ -19,6 +19,15 @@ def __init__(self, root):
1919 self .root .geometry ("750x600" )
2020 self .root .resizable (True , True )
2121
22+ #替换Tkinter默认窗口图标
23+ if getattr (sys , 'frozen' , False ):
24+ # 打包后 exe 运行时
25+ icon_path = os .path .join (sys ._MEIPASS , "icon.ico" )
26+ else :
27+ # 源码运行时
28+ icon_path = os .path .join (os .path .dirname (__file__ ), ".." , "icon.ico" )
29+ self .root .iconbitmap (icon_path )
30+
2231 self .config = ConfigManager ()
2332 self .style_manager = StyleManager (root )
2433
@@ -31,13 +40,20 @@ def __init__(self, root):
3140 self .log_widget .log ("欢迎使用文件分割工具" )
3241 self .log_widget .log ("请选择输入文件和输出目录" )
3342
43+ self .root .protocol ("WM_DELETE_WINDOW" , self .on_closing )#临死前的挣扎(保存配置)
44+
3445 # ---------- 事件绑定 ----------
3546 def bind_setting_changes (self ):
3647 self .chars_entry .entry .bind ("<FocusOut>" , self .save_settings )
3748 self .encoding_combo .combo .bind ("<<ComboboxSelected>>" , self .save_settings )
3849 self .output_encoding_combo .combo .bind ("<<ComboboxSelected>>" , self .save_settings )
3950 self .line_mode_combo .combo .bind ("<<ComboboxSelected>>" , self .save_settings )
4051
52+ def on_closing (self ):
53+ """窗口关闭时保存设置再退出"""
54+ self .save_settings () # 把当前输入写进配置文件
55+ self .root .destroy () # 真正关闭窗口
56+
4157 # ---------- 应用保存的设置 ----------
4258 def apply_saved_font_settings (self ):
4359 font_family = self .config .get_setting ('Settings' , 'font_family' , '微软雅黑' )
@@ -56,24 +72,32 @@ def apply_saved_settings(self):
5672 if mode == "按行分割" :
5773 val = self .config .get_setting ('Settings' , 'lines_per_file' , '1000' )
5874 self .chars_entry .set_value (val )
59- self .chars_entry .set_label_text ("每个文件的行数:" )
60- else :
75+ self .chars_entry .set_label_text ("每份文件的字符数/行数/份数:" )
76+
77+ elif mode == "份数分割" :
78+ val = self .config .get_setting ('Settings' , 'parts_per_file' , '4' )
79+ self .chars_entry .set_value (val )
80+ self .chars_entry .set_label_text ("每份文件的字符数/行数/份数:" )
81+
82+ else : # 按字符 / 严格行 / 灵活行 都走这里
6183 val = self .config .get_setting ('Settings' , 'chars_per_file' , '1000' )
6284 self .chars_entry .set_value (val )
63- self .chars_entry .set_label_text ("每个文件的字符数:" )
64- # 恢复编码下拉框
85+ self .chars_entry .set_label_text ("每份文件的字符数/行数/份数:" )
86+
87+ # 3. 恢复编码下拉框
6588 in_enc = self .config .get_setting ('Settings' , 'input_encoding' , 'auto' )
6689 out_enc = self .config .get_setting ('Settings' , 'output_encoding' , '同输入编码' )
6790 self .encoding_combo .set_value (in_enc )
6891 self .output_encoding_combo .set_value (out_enc )
69-
7092 # ---------- 保存设置 ----------
7193 def save_settings (self , event = None ):
7294 mode = self .line_mode_combo .get_value ()
7395 self .config .set_setting ('Settings' , 'split_mode' , mode )
7496
7597 if mode == "按行分割" :
7698 self .config .set_setting ('Settings' , 'lines_per_file' , self .chars_entry .get_value ())
99+ elif mode == "份数分割" :
100+ self .config .set_setting ('Settings' , 'parts_per_file' , self .chars_entry .get_value ())
77101 else :
78102 self .config .set_setting ('Settings' , 'chars_per_file' , self .chars_entry .get_value ())
79103
@@ -134,18 +158,17 @@ def create_widgets(self):
134158 self .output_entry .grid (row = 2 , column = 0 , columnspan = 3 , sticky = "ew" , pady = 5 )
135159
136160 self .chars_entry = LabelledEntry (
137- self .main_frame , "每个文件的字符数:" ,
161+ self .main_frame , "每个文件的字符数/行数/份数 :" ,
138162 default_value = "1000" , entry_width = 15 )
139163 self .chars_entry .grid (row = 3 , column = 0 , columnspan = 3 , sticky = "w" , pady = 5 )
140164
141165 split_frame = ttk .Frame (self .main_frame )
142166 split_frame .grid (row = 4 , column = 0 , columnspan = 3 , sticky = "ew" , pady = 5 )
143167 ttk .Label (split_frame , text = "分割方式:" , style = "Label.TLabel" ).pack (side = tk .LEFT , padx = (0 , 10 ))
144168 self .line_mode_combo = LabelledCombobox (
145- split_frame , "" , values = ["按字符分割" , "按行分割" , "严格行分割" , "灵活行分割" ],
169+ split_frame , "" , values = ["按字符分割" , "按行分割" , "严格行分割" , "灵活行分割" , "份数分割" ],
146170 default_value = "按字符分割" , width = 15 )
147171 self .line_mode_combo .pack (side = tk .LEFT )
148- self .line_mode_combo .combo .bind ("<<ComboboxSelected>>" , self .on_split_mode_changed )
149172
150173 enc_frame = ttk .Frame (self .main_frame )
151174 enc_frame .grid (row = 5 , column = 0 , columnspan = 3 , sticky = "ew" , pady = 5 )
@@ -185,32 +208,8 @@ def create_widgets(self):
185208 self .log_widget .grid (row = 9 , column = 0 , columnspan = 3 , sticky = "nsew" )
186209 self .main_frame .columnconfigure (0 , weight = 1 )
187210 self .main_frame .rowconfigure (9 , weight = 1 )
188- self .line_mode_combo .combo .bind ("<<ComboboxSelected>>" , self .on_split_mode_changed )
189211 self .bind_setting_changes ()
190212
191- def on_split_mode_changed (self , event = None ):
192- """下拉框切换时即时更新界面"""
193- mode = self .line_mode_combo .get_value ()
194- if mode == "按行分割" :
195- self .chars_entry .set_label_text ("每个文件的行数:" )
196- val = self .config .get_setting ('Settings' , 'lines_per_file' , '1000' )
197- else :
198- self .chars_entry .set_label_text ("每个文件的字符数:" )
199- val = self .config .get_setting ('Settings' , 'chars_per_file' , '1000' )
200- self .chars_entry .set_value (val )
201- self .root .update_idletasks () # 立即刷新
202-
203- # ---------- 下拉框切换 ----------
204- def on_split_mode_changed (self , event = None ):
205- mode = self .line_mode_combo .get_value ()
206- if mode == "按行分割" :
207- self .chars_entry .set_label_text ("每个文件的行数:" )
208- val = self .config .get_setting ('Settings' , 'lines_per_file' , '1000' )
209- else :
210- self .chars_entry .set_label_text ("每个文件的字符数:" )
211- val = self .config .get_setting ('Settings' , 'chars_per_file' , '1000' )
212- self .chars_entry .set_value (val )
213-
214213 # ---------- 字体设置 ----------
215214 def open_font_settings (self ):
216215 FontSettingsDialog (
@@ -255,7 +254,24 @@ def start_split(self):
255254 target = self .run_split_by_lines ,
256255 args = (input_path , output_dir , lines , in_enc , out_enc ),
257256 daemon = True ).start ()
257+ elif mode == "份数分割" :
258+ try :
259+ parts = int (self .chars_entry .get_value ())
260+ if parts <= 0 :
261+ raise ValueError
262+ except ValueError :
263+ messagebox .showerror ("错误" , "请输入有效的份数" )
264+ return
265+
266+ self .open_output_btn .config (state = tk .DISABLED )
267+ self .start_btn .config (state = tk .DISABLED )
268+ self .progress_var .set (0 )
269+ self .status_var .set ("开始按份数分割..." )
258270
271+ threading .Thread (
272+ target = self .run_split_by_parts ,
273+ args = (input_path , output_dir , parts , in_enc , out_enc ),
274+ daemon = True ).start ()
259275 else :
260276 try :
261277 chars = int (self .chars_entry .get_value ())
@@ -316,4 +332,15 @@ def on_split_error(self, e):
316332 self .progress_var .set (0 )
317333 self .status_var .set ("处理出错" )
318334 messagebox .showerror ("错误" , str (e ))
319- self .start_btn .config (state = tk .NORMAL )
335+ self .start_btn .config (state = tk .NORMAL )
336+
337+ def run_split_by_parts (self , * args ):
338+ try :
339+ from core .splitter import split_file_by_parts
340+ num = split_file_by_parts (
341+ * args ,
342+ progress_callback = self .update_progress ,
343+ log_callback = self .log_in_ui_thread )
344+ self .root .after (0 , self .on_split_completed , num )
345+ except Exception as e :
346+ self .root .after (0 , self .on_split_error , e )
0 commit comments