Search code examples
pythontkinterfrontendframeworksbackend

How Can I Delete Written Number, Python Code?


When i say clear in the transaction screen(to clean the values or names i typed for entry date, unit code, etc…) it doesnt clear "unit code, customer number and group code’s first number". I cant delete it manually too. can you fix this please. Others work fine (such as entry date, customer name, currency, type…). I cant delete when im creating a new customer too. And lets say Unit code is 25567 if i delete manually in order "5,2,5,7" then 6 is the only number remaining and I cant delete 6.

code:

import tkinter as tk
from tkinter import messagebox
from tkcalendar import DateEntry

# Define the main application class
class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Banking Application")
        self.geometry("800x600")
        self.current_frame = None
        self.transactions = []
        self.show_login_screen()

    # Method to show the login screen
    def show_login_screen(self):
        if self.current_frame is not None:
            self.current_frame.destroy()
        self.current_frame = LoginFrame(self)
        self.current_frame.pack(fill="both", expand=True)

    # Method to show the menu screen
    def show_menu_screen(self):
        if self.current_frame is not None:
            self.current_frame.destroy()
        self.current_frame = MenuFrame(self)
        self.current_frame.pack(fill="both", expand=True)

    # Method to show the transaction info screen
    def show_transaction_info_screen(self):
        if self.current_frame is not None:
            self.current_frame.destroy()
        self.current_frame = TransactionInfoFrame(self)
        self.current_frame.pack(fill="both", expand=True)

    # Method to show the new customer screen
    def show_new_customer_screen(self):
        if self.current_frame is not None:
            self.current_frame.destroy()
        self.current_frame = NewCustomerFrame(self)
        self.current_frame.pack(fill="both", expand=True)

# Define the login frame class
class LoginFrame(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master

        # Create a frame for the username and password labels and entries
        login_frame = tk.Frame(self)
        login_frame.pack(pady=20)

        # Username label and entry
        tk.Label(login_frame, text="Username:").grid(row=0, column=0, padx=10, pady=10)
        self.username_entry = tk.Entry(login_frame)
        self.username_entry.grid(row=0, column=1, padx=10, pady=10)

        # Password label and entry
        tk.Label(login_frame, text="Password:").grid(row=1, column=0, padx=10, pady=10)
        self.password_entry = tk.Entry(login_frame, show="*")
        self.password_entry.grid(row=1, column=1, padx=10, pady=10)

        # Submit and Logout buttons
        button_frame = tk.Frame(self)
        button_frame.pack(pady=20)
        tk.Button(button_frame, text="Submit", command=self.login).grid(row=0, column=0, padx=10)
        tk.Button(button_frame, text="Logout", command=self.logout).grid(row=0, column=1, padx=10)

    # Method to handle login
    def login(self):
        username = self.username_entry.get()
        password = self.password_entry.get()
        # Add login validation logic here
        if username == "admin" and password == "password":  # Example validation
            self.master.show_menu_screen()
        else:
            messagebox.showerror("Login Failed", "Invalid username or password")

    # Method to handle logout
    def logout(self):
        self.master.destroy()

# Define the menu frame class
class MenuFrame(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master

        # Menu label and buttons
        tk.Label(self, text="Menu").pack(pady=20)
        tk.Button(self, text="Transaction Info", command=self.master.show_transaction_info_screen).pack(pady=10)
        tk.Button(self, text="New Customer", command=self.master.show_new_customer_screen).pack(pady=10)

# Define the transaction info frame class
class TransactionInfoFrame(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master

        # Transaction info label and listbox with scrollbar
        tk.Label(self, text="Transaction Info").pack(pady=20)
        self.transaction_list_frame = tk.Frame(self)
        self.transaction_list_frame.pack(pady=20, fill=tk.BOTH, expand=True)

        self.transaction_list_scrollbar = tk.Scrollbar(self.transaction_list_frame)
        self.transaction_list_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.transaction_list = tk.Listbox(self.transaction_list_frame, yscrollcommand=self.transaction_list_scrollbar.set)
        self.transaction_list.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        self.transaction_list_scrollbar.config(command=self.transaction_list.yview)

        self.refresh_transactions()

        # Update, Cancel, and Exit buttons
        tk.Button(self, text="Update", command=self.update_transaction).pack(pady=10)
        tk.Button(self, text="Cancel", command=self.cancel_transaction).pack(pady=10)
        tk.Button(self, text="Exit", command=self.master.show_menu_screen).pack(pady=10)

    # Method to refresh the transaction list
    def refresh_transactions(self):
        self.transaction_list.delete(0, tk.END)
        for transaction in self.master.transactions:
            self.transaction_list.insert(tk.END, transaction["Customer Name"])

    # Method to handle update transaction
    def update_transaction(self):
        selected_index = self.transaction_list.curselection()
        if selected_index:
            selected_transaction = self.master.transactions[selected_index[0]]
            self.master.show_new_customer_screen()
            self.master.current_frame.fill_form(selected_transaction, selected_index[0])

    # Method to handle cancel transaction
    def cancel_transaction(self):
        selected_index = self.transaction_list.curselection()
        if selected_index:
            del self.master.transactions[selected_index[0]]
            self.refresh_transactions()

# Define the new customer frame class
class NewCustomerFrame(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master
        self.edit_index = None
        self.create_form()

        # Submit, Clear, Back, Delete, and Exit buttons
        tk.Button(self, text="Submit", command=self.submit_customer).pack(pady=10)
        tk.Button(self, text="Clear", command=self.clear_form).pack(pady=10)
        tk.Button(self, text="Back", command=self.master.show_menu_screen).pack(pady=10)
        tk.Button(self, text="Delete", command=self.delete_customer).pack(pady=10)
        tk.Button(self, text="Exit", command=self.master.show_menu_screen).pack(pady=10)

    # Method to create the new customer form with scrollbar
    def create_form(self):
        form_frame = tk.Frame(self)
        form_frame.pack(pady=20, fill=tk.BOTH, expand=True)

        form_canvas = tk.Canvas(form_frame)
        form_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        scrollbar = tk.Scrollbar(form_frame, orient="vertical", command=form_canvas.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        form_scrollable_frame = tk.Frame(form_canvas)

        form_scrollable_frame.bind(
            "<Configure>",
            lambda e: form_canvas.configure(
                scrollregion=form_canvas.bbox("all")
            )
        )

        form_canvas.create_window((0, 0), window=form_scrollable_frame, anchor="nw")
        form_canvas.configure(yscrollcommand=scrollbar.set)

        form_scrollable_frame.bind_all("<MouseWheel>", lambda event: form_canvas.yview_scroll(int(-1*(event.delta/120)), "units"))

        fields = [
            ("Entry Date", "Enter the date the customer was added."),
            ("Unit Code", "Enter the branch number (max 3 digits)."),
            ("Customer Number", "Enter the customer number (max 5 digits)."),
            ("Group Code", "Enter the group code (max 1 digit)."),
            ("Customer Name", "Enter the customer's full name."),
            ("Currency Type", "Enter the type of currency (e.g., USD, EUR)."),
            ("Interest Rate", "Enter the interest rate."),
            ("Minimum Amount", "Enter the minimum amount."),
            ("Maximum Amount", "Enter the maximum amount."),
            ("Balance", "Enter the balance."),
            ("Maturity Start", "Enter the start date of the maturity period."),
            ("Maturity End", "Enter the end date of the maturity period."),
            ("Number of Days", "Calculated number of days between maturity start and end."),
            ("Pricing Authority", "Enter the pricing authority.")
        ]
        self.entries = {}
        for field, instruction in fields:
            frame = tk.Frame(form_scrollable_frame)
            frame.pack(fill=tk.X, padx=5, pady=5)
            tk.Label(frame, text=field).pack(side=tk.LEFT)
            if "Date" in field or "Maturity" in field:
                entry = DateEntry(frame, date_pattern='dd/mm/yyyy')
            else:
                entry = tk.Entry(frame)
                if "Customer Number" in field:
                    entry.config(validate="key", validatecommand=(frame.register(self.validate_customer_number), '%P'))
                elif "Unit Code" in field:
                    entry.config(validate="key", validatecommand=(frame.register(self.validate_unit_code), '%P'))
                elif "Group Code" in field:
                    entry.config(validate="key", validatecommand=(frame.register(self.validate_group_code), '%P'))
            entry.pack(side=tk.RIGHT, fill=tk.X, expand=True)
            tk.Label(frame, text=instruction, fg="grey").pack(side=tk.RIGHT, padx=5)
            self.entries[field] = entry

    def validate_customer_number(self, value):
        return value.isdigit() and len(value) <= 5

    def validate_unit_code(self, value):
        return value.isdigit() and len(value) <= 3

    def validate_group_code(self, value):
        return value.isdigit() and len(value) <= 1

    # Method to handle submit customer
    def submit_customer(self):
        customer_data = {field: entry.get() for field, entry in self.entries.items()}
        if self.edit_index is not None:
            self.master.transactions[self.edit_index] = customer_data
            self.edit_index = None
        else:
            self.master.transactions.append(customer_data)
        messagebox.showinfo("Submitted", "Customer information has been submitted")
        print(customer_data)
        self.master.show_menu_screen()

    # Method to fill the form with existing data
    def fill_form(self, data, index):
        self.edit_index = index
        for field, value in data.items():
            self.entries[field].delete(0, tk.END)
            self.entries[field].insert(0, value)

    # Method to clear the form
    def clear_form(self):
        for entry in self.entries.values():
            entry.delete(0, tk.END)

    # Method to delete the customer
    def delete_customer(self):
        if self.edit_index is not None:
            del self.master.transactions[self.edit_index]
            self.edit_index = None
            messagebox.showinfo("Deleted", "Customer information has been deleted")
            self.clear_form()
            self.master.show_menu_screen()
        else:
            messagebox.showerror("Error", "No customer selected to delete")

# Main application entry point
if __name__ == "__main__":
    app = Application()
    app.mainloop()




Solution

  • The problem is with the validate functions of these three entries, you are using this expression for all

    value.isdigit() and len(value) <= 5
    

    Now when you press the clear button, the key that actually being pass is an empty string"", and an empty string is not a digit so the condition will be False and it will not update the entries, so for you have to update all of these functions to this

        def validate_customer_number(self, value):
            return (value.isdigit() and len(value) <= 5) or not value
    
        def validate_unit_code(self, value):
            return (value.isdigit() and len(value) <= 3) or not value
    
        def validate_group_code(self, value):
            return (value.isdigit() and len(value) <= 1) or not value
    

    adding or not value: it means that this functions will return true if the requirement is correct OR OR the passed value is an empty string.