From 49eb37e50c413197c445bacdb105e0b952c4373b Mon Sep 17 00:00:00 2001 From: yuxing Date: Tue, 13 May 2025 19:10:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0disclaimer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Robocopy_GUI/robocopy_mirror_gui.py | 49 ++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/Robocopy_GUI/robocopy_mirror_gui.py b/Robocopy_GUI/robocopy_mirror_gui.py index e5b5cf4..3e1007a 100644 --- a/Robocopy_GUI/robocopy_mirror_gui.py +++ b/Robocopy_GUI/robocopy_mirror_gui.py @@ -23,7 +23,8 @@ class RobocopyMirrorApp: # Renamed class for clarity self.root = root # Updated Title self.root.title("Robocopy Mirror GUI") - self.root.geometry("700x500") # Adjust size as needed + self.root.geometry("700x550") # Initial size + self.root.minsize(700, 550) # Set minimum window size # Check OS if platform.system() != "Windows": @@ -38,8 +39,13 @@ class RobocopyMirrorApp: # Renamed class for clarity self.is_running = False # --- GUI Elements --- + # Main content frame (to allow disclaimer to be packed at the bottom of root) + main_content_frame = ttk.Frame(root) + main_content_frame.pack(fill=tk.BOTH, expand=True) + + # Frame for inputs - input_frame = ttk.Frame(root, padding="10") + input_frame = ttk.Frame(main_content_frame, padding="10") input_frame.pack(fill=tk.X) # Source Row @@ -59,18 +65,24 @@ class RobocopyMirrorApp: # Renamed class for clarity # Configure input frame column weights for resizing input_frame.columnconfigure(1, weight=1) - # Run Button (Text could be changed to "Run Mirror" but "Run Robocopy" is fine) - self.run_button = ttk.Button(root, text="Run Robocopy Mirror", command=self.start_robocopy_thread) + # Run Button + self.run_button = ttk.Button(main_content_frame, text="Run Robocopy Mirror", command=self.start_robocopy_thread) self.run_button.pack(pady=10) # Output Area Frame - output_frame = ttk.Frame(root, padding="10") + output_frame = ttk.Frame(main_content_frame, padding="10") output_frame.pack(fill=tk.BOTH, expand=True) ttk.Label(output_frame, text="Robocopy Output:").pack(anchor=tk.W) self.output_text = scrolledtext.ScrolledText(output_frame, wrap=tk.WORD, height=15, state='disabled') self.output_text.pack(fill=tk.BOTH, expand=True, pady=5) + # --- Disclaimer Label --- + # Packed directly into root, so it stays at the very bottom and can be centered + disclaimer_label = ttk.Label(root, text="Ver. 2.0 @杨昱幸. All Rights Reserved.", font=("Arial", 8)) + disclaimer_label.pack(side=tk.BOTTOM, pady=(5, 10)) # Centered by default when using pack with side=BOTTOM + + # --- Start queue check --- self.check_queue() # Start checking the queue for updates @@ -141,11 +153,15 @@ class RobocopyMirrorApp: # Renamed class for clarity # Read output line by line for line in iter(self.process.stdout.readline, ''): - if not line: + if not line: # Check if process has exited break self.output_queue.put(line) + if self.process.poll() is not None and not line: # Double check if process ended and no more output + break - self.process.stdout.close() + + if self.process.stdout: + self.process.stdout.close() return_code = self.process.wait() # Send completion message based on return code @@ -189,7 +205,7 @@ class RobocopyMirrorApp: # Renamed class for clarity def on_robocopy_complete(self): """Called when the robocopy process finishes.""" self.run_button.config(state='normal') - self.output_text.config(state='disabled') + # self.output_text.config(state='disabled') # Keep enabled to allow copy-paste self.process = None self.is_running = False messagebox.showinfo("Finished", "Robocopy Mirror process has completed.") @@ -199,15 +215,18 @@ class RobocopyMirrorApp: # Renamed class for clarity if self.is_running and self.process: if messagebox.askyesno("Quit", "Robocopy might still be running. Terminate it and exit?"): try: - self.process.terminate() - self.process.wait(timeout=2) - except subprocess.TimeoutExpired: - self.process.kill() - except Exception: + self.process.terminate() # Ask nicely first + try: + self.process.wait(timeout=2) # Give it a moment + except subprocess.TimeoutExpired: + self.process.kill() # Force kill if necessary + except Exception: # Handle other wait errors + pass + except Exception: # Handle errors during terminate/kill (e.g., process already ended) pass self.root.destroy() else: - return + return # Don't close if user says no else: self.root.destroy() @@ -217,4 +236,4 @@ if __name__ == "__main__": # Use the renamed class app = RobocopyMirrorApp(root) root.protocol("WM_DELETE_WINDOW", app.on_closing) - root.mainloop() \ No newline at end of file + root.mainloop()