You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter Entry组件新增数据时替换列表项而非追加的问题排查

Fixing the Job List Overwrite Issue in Your Tkinter App

Hey Lucy, I see exactly what's going on here—your job_list keeps getting replaced instead of appending new entries because of a small but critical mistake in how you're initializing your lists. Let's break this down and fix it step by step.

The Root Cause

Take a look at your store_job method:

def store_job(self):
    self.job_list = []  # This resets the list EVERY time you click the button!
    self.customer_list = []
    self.job_list.append(self.job_number.get())
    self.customer_list.append(self.customer_name.get())
    for i in self.job_list:
        print (i)

Every time you click "Enter Job", you're creating brand new empty lists for job_list and customer_list. That means any previous entries get wiped out immediately before adding the new one. The same problem applies to cost_list in your calculate method—you're resetting it every time too, so only the latest cost gets stored.

The Fix

Move the initialization of your lists to the __init__ method so they're only created once when the GUI starts, not every time you add a job. Here's how to adjust your code:

Step 1: Initialize Lists in __init__

Add these lines inside your __init__ function, right after you set up self.cb:

# Initialize empty storage lists ONCE when the app launches
self.job_list = []
self.customer_list = []
self.cost_list = []

Step 2: Update store_job to Append Only

Remove the list reset lines from store_job—now it will add to the existing lists instead of replacing them:

def store_job(self):
    # Add new entries to the pre-initialized lists
    self.job_list.append(self.job_number.get())
    self.customer_list.append(self.customer_name.get())
    # Optional: Print all jobs to confirm they're being stored correctly
    print("Current job numbers:", self.job_list)

Step 3: Fix calculate to Stop Resetting cost_list

Similarly, remove the self.cost_list = [] line from calculate so it appends new costs instead of overwriting:

def calculate(self):
    self.distance_calc = int(self.distance.get())
    self.min_calc = int(self.min_spent.get())
    self.cost = 0
    # ... (keep your existing cost calculation logic here) ...
    self.cost_list.append(self.cost)
    print("Current job costs:", self.cost_list)
    self.enter_next()

Full Modified Code

Here's the complete updated code with all fixes applied, plus a bonus feature for the "Show All" button:

from tkinter import * 

class EntryGUI: 
    def __init__(self, parent): 
        self.cb = IntVar()
        # Initialize storage lists ONCE here
        self.job_list = []
        self.customer_list = []
        self.cost_list = []

        self.job_number_label= Label(parent, text = "Job number:") 
        self.job_number_label.grid(row = 1, column = 0) 
        self.job_number = Entry(parent) 
        self.job_number.focus() 
        self.job_number.grid(row=1, column = 1) 

        self.customer_name_label = Label(parent, text = "Customer name:") 
        self.customer_name_label.grid(row = 2, column = 0) 
        self.customer_name = Entry(parent) 
        self.customer_name.grid(row=2, column = 1) 

        self.distance_label= Label(parent, text = "Distance Travelled (km):") 
        self.distance_label.grid(row = 3, column = 0) 
        self.distance = Entry(parent) 
        self.distance.grid(row=3, column = 1) 

        self.min_spent_label= Label(parent, text = "Minutes spent on Virus protection:") 
        self.min_spent_label.grid(row = 4, column = 0) 
        self.min_spent = Entry(parent) 
        self.min_spent.grid(row=4, column = 1) 

        wof_tune= Checkbutton(parent, variable = self.cb, text = "check if WOF and tune is required", onvalue = 100, offvalue = 0) 
        wof_tune.grid(row = 5, column = 0) 

        self.enter = Button(parent, text = "Enter Job", command = lambda:[self.store_job(),self.calculate()]) 
        self.enter.grid(row = 6, column = 0) 

        self.show_all = Button(parent, text = "Show All", command=self.display_jobs)  # Linked to new display function
        self.show_all.grid(row = 6, column = 1) 

    def store_job(self): 
        # Append to existing lists instead of resetting
        self.job_list.append(self.job_number.get()) 
        self.customer_list.append(self.customer_name.get()) 
        print("Stored jobs:", self.job_list)

    def calculate(self): 
        self.distance_calc = int(self.distance.get()) 
        self.min_calc = int(self.min_spent.get()) 
        self.cost = 0 

        # Travel cost calculation
        if self.distance_calc <= 5: 
            self.cost = 10 
        else: 
            self.distance_calc = self.distance_calc - 5 
            self.distance_calc = self.distance_calc / 2 
            self.cost = self.distance_calc + 10 

        # Add virus protection and WOF/tune costs
        self.cost = self.cost + (self.min_calc * 0.8) 
        self.cost = self.cost + int(self.cb.get()) 
        self.cost_list.append(self.cost) 
        print("Calculated costs:", self.cost_list)
        self.enter_next() 

    def enter_next(self): 
        self.job_number.delete(0,END) 
        self.customer_name.delete(0, END) 
        self.distance.delete(0, END) 
        self.min_spent.delete(0, END) 
        self.enter.configure(state = NORMAL) 

    # Added method to display all jobs when "Show All" is clicked
    def display_jobs(self):
        # Create a new window to show all job details
        job_window = Toplevel()
        job_window.title("All Jobs")
        # Display table headers
        Label(job_window, text="Job Number", font=("Arial", 10, "bold")).grid(row=0, column=0, padx=10, pady=5)
        Label(job_window, text="Customer Name", font=("Arial", 10, "bold")).grid(row=0, column=1, padx=10, pady=5)
        Label(job_window, text="Total Cost", font=("Arial", 10, "bold")).grid(row=0, column=2, padx=10, pady=5)
        # Populate job data
        for idx, (job_num, cust_name, cost) in enumerate(zip(self.job_list, self.customer_list, self.cost_list), start=1):
            Label(job_window, text=job_num).grid(row=idx, column=0, padx=10, pady=2)
            Label(job_window, text=cust_name).grid(row=idx, column=1, padx=10, pady=2)
            Label(job_window, text=f"${cost:.2f}").grid(row=idx, column=2, padx=10, pady=2)

if __name__=="__main__": 
    root = Tk() 
    show_label = EntryGUI(root) 
    root.mainloop() 

Bonus Improvements

I added a display_jobs method and linked it to the "Show All" button so you can view all stored jobs and their formatted costs in a new window.

Another thing to consider: adding input validation to your Entry fields (like checking that distance/minutes are numbers) to avoid ValueError when users enter non-numeric data. For example, you could use a validation command to only allow digits in those fields.

内容的提问来源于stack exchange,提问作者Lucy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:07:42