如何实现Tkinter按钮清除旧消息并显示新内容+代码精简优化
Hey there! Let's fix two key issues here: clearing old results when you click the ROLL button, and trimming down that repetitive code to make it cleaner and easier to maintain. Here's how we can do it:
Core Fix: Clear Old Results
Your original code creates new Label widgets every time you click ROLL, leaving old results cluttering the window. The simplest solution is to use a container Frame to hold all result labels—then we just empty this frame before generating new results each time.
Code Simplification Tips
- Ditch the nested
rollstatfunction and replace it with a modular function that returns values directly (no more messyglobalvariables) - Use a loop instead of writing the same code 6 times for each stat
- Simplify dice-rolling logic with list comprehensions
- Clean up layout code for better readability
Modified Full Code
import tkinter import random window = tkinter.Tk() window.title("D&D Stat Roller") window.geometry("600x350") # Slightly larger window to fit results nicely # Fixed header and instructions start_label = tkinter.Label(window, text="Welcome to D&D Stat Roller") start_label.pack(pady=(10, 0)) how_to = tkinter.Label(window, text="Rolled stats are determined by rolling a d6 4 times and subtracting the lowest number.") how_to.pack(pady=(0, 10)) # Frame to hold all roll results (easy to clear later) results_frame = tkinter.Frame(window) results_frame.pack(fill="both", expand=True) def roll_single_stat(): """Generate one stat: returns (list of 4 dice rolls, calculated stat value)""" dice_rolls = [random.randint(1, 6) for _ in range(4)] stat_value = sum(dice_rolls) - min(dice_rolls) return dice_rolls, stat_value def roll_stats(): # Clear all old results first for widget in results_frame.winfo_children(): widget.destroy() total_value = 0 stats = [] # Generate 6 stats with a loop (no more repeated code!) for stat_num in range(6): dice, stat = roll_single_stat() stats.append(stat) # Add result label to the results frame result_label = tkinter.Label(results_frame, text=f"{stat_num+1}th rolled stat: {dice}. Stat value: {stat}") result_label.pack(anchor="w", padx=20) # Display total stat value total_label = tkinter.Label(results_frame, text=f"\nYour full stat total is {sum(stats)}/108", font=("Arial", 10, "bold")) total_label.pack(pady=(10, 0), padx=20) # Roll button with improved styling roll_button = tkinter.Button(window, text="ROLL!", command=roll_stats, font=("Arial", 12, "bold")) roll_button.pack(pady=10) window.mainloop()
Key Changes Explained
- Results Container Frame: The
results_frameholds all dynamic result labels. We clear it by iterating over its child widgets and destroying each one before generating new results. - Modular Stat Generation:
roll_single_stat()handles all logic for one stat roll, returning both the raw dice values and the final stat—no global variables needed. - Loop for Stats: A simple
forloop replaces 6 identical blocks of code, making the code shorter and easier to adjust (e.g., change the number of stats just by modifying the loop range). - Cleaner Layout: Added padding (
padx/pady) and bold text for the total to make the UI more readable.
内容的提问来源于stack exchange,提问作者S3thar
相关产品推荐
相关产品推荐

