Salary Calculator using Setting tab and storing data in JSON file


Building a Tkinter GUI: Managing Application Settings with JSON #json #tkinter

This Tkinter-based GUI application calculates salaries based on user-defined settings stored in a JSON file.

1. General Application Requirements

  • The application is a Tkinter-based GUI with multiple tabs.
  • It provides a Salary Calculator and a Settings Panel.
  • User settings are stored in a settings.json file to retain preferences across sessions.

2. Settings and Configuration Requirements


Salary calculation using Json data as variables

Default Settings:
  • DA Percentage: 20%
  • HRA Percentage: 10%
  • Medical Allowance: ₹500
  • Transport Allowance: ₹300
  • Employee Type: "Regular"
  • Shift Allowance: ₹200
Settings Storage and Retrieval:
  • Settings are loaded from a JSON file at startup.
  • If any key is missing, it is automatically assigned a default value.
  • Users can modify settings via the GUI and save them back to the JSON file.

3. Salary Calculation Requirements


Settings to update Json file for Salary calculation

Fixed Components:
  • Basic Pay: ₹5000
  • Grade Pay: ₹1300 (Fixed and does not change)
Dynamic Components Based on User Settings:
  • DA (Dearness Allowance) – Based on a percentage of Basic Pay.
  • HRA (House Rent Allowance) – Based on a percentage of Basic Pay.
  • Medical Allowance – Directly taken from JSON settings.
  • Transport Allowance – Directly taken from JSON settings.
  • Shift Allowance:
    • Only included if Employee Type = "Regular".
    • If the employee is on a contract, Shift Allowance is set to 0.

4. User Interface (UI) Requirements

4.1 Home Tab (Salary Breakdown)
  • Displays salary components and their respective amounts.
  • Color Coding:
    • Blue – Fixed salary values (Basic Pay, Grade Pay, Shift Allowance).
    • Orange – Values linked to Basic Pay (DA, HRA).
    • Red – Other allowances (Medical Allowance, Transport Allowance).
    • Green – Total Salary.
4.2 Settings Tab (User-Configurable Fields)
  • DA Percentage (0% - 100%) – Controlled via Slider.
  • HRA Percentage (0% - 100%) – Controlled via Slider.
  • Medical Allowance (₹0 - ₹1000) – Controlled via Spinbox.
  • Transport Allowance (₹0 - ₹1000) – Controlled via Spinbox.
  • Employee Type – Controlled via Radio Button:
    • "Regular" (Default)
    • "Contract"
  • Shift Allowance (₹0 - ₹1000) – Controlled via Spinbox.
    • Only applies when Employee Type is "Regular".
  • Save Button:
    • Saves all modified values into the JSON file.
    • Triggers salary recalculation and UI update.

5. Functional Requirements

Startup Behavior:
  • Loads settings from settings.json.
  • Initializes UI elements with stored values.
  • Displays salary breakdown.
Event Handling:
  • Updating values in the Settings Tab updates variables immediately.
  • Clicking Save writes the values to JSON and refreshes the salary breakdown.
Error Handling & Data Validation:
  • If settings.json is missing, the application creates it with default values.
  • Ensures that all expected keys exist in the settings dictionary.
  • If invalid values are encountered, they are replaced with default values.

6. File Management & Data Persistence

File Location:
  • JSON file path: E:\testing\settings.json
Data Handling:
  • Reads JSON settings on startup (load_settings()).
  • Updates values when users modify settings (save_settings()).
  • Saves data back to JSON when the Save button is clicked.
---

Script details

1. Import Required Modules

import tkinter as tk  
from tkinter import ttk  
import json  
import os  
  • tkinter: Used for creating GUI
  • ttk: Provides themed widgets
  • json: Used for reading & writing settings
  • os: To check if settings file exists
---

2. Define JSON Storage

We define the file path for storing settings and provide default values for allowances and employee type.

SETTINGS_FILE = "F:\\testing\\settings.json" # Update your path

DEFAULT_SETTINGS = {
    "da_percent": 20,  
    "hra_percent": 10,  
    "medical_allowance": 500,  
    "transport_allowance": 300,  
    "employee_type": "Regular",  
    "shift_allowance": 200  
}
---

3. Loading & Saving Settings

Loading Settings from JSON

def load_settings():
    if os.path.exists(SETTINGS_FILE):
        with open(SETTINGS_FILE, "r") as file:
            data = json.load(file)
    else:
        data = DEFAULT_SETTINGS
    return data

Saving Settings to JSON

def save_settings():
    settings = {
        "da_percent": da_var.get(),
        "hra_percent": hra_var.get(),
        "medical_allowance": medical_var.get(),
        "transport_allowance": transport_var.get(),
        "employee_type": emp_type_var.get(),
        "shift_allowance": shift_allowance_var.get() if emp_type_var.get() == "Regular" else 0
    }
    with open(SETTINGS_FILE, "w") as file:
        json.dump(settings, file, indent=4)
---

4. GUI Layout (Notebook with Two Tabs)

We use a Notebook widget to create two tabs:

  • Home Tab - Displays salary breakdown
  • Settings Tab - Allows users to adjust allowances
---

5. Salary Breakdown Tab

The salary is calculated dynamically based on user settings.

home_frame = tk.Frame(notebook, bg="#FFFACD")
notebook.add(home_frame, text="Salary Breakdown")
---

6. Settings Tab UI

Users can adjust allowances, DA, and HRA through sliders and spinboxes.

settings_frame = tk.Frame(notebook, bg="#FFCCCB")
notebook.add(settings_frame, text="Settings")
---

import tkinter as tk
from tkinter import ttk
import json
import os

# JSON file path
SETTINGS_FILE = "E:\\testing\\settings.json"

# Default settings
DEFAULT_SETTINGS = {
    "da_percent": 20,  
    "hra_percent": 10,  
    "medical_allowance": 500,  
    "transport_allowance": 300,  
    "employee_type": "Regular",  
    "shift_allowance": 200  
}

# Function to load settings from JSON file
def load_settings():
    if os.path.exists(SETTINGS_FILE):
        with open(SETTINGS_FILE, "r") as file:
            data = json.load(file)
        
        # Ensure all required keys exist, otherwise, assign default values
        for key, default_value in DEFAULT_SETTINGS.items():
            if key not in data:
                data[key] = default_value
        
        return data
    else:
        return DEFAULT_SETTINGS

# Function to save settings to JSON file
def save_settings():
    settings = {
        "da_percent": da_var.get(),
        "hra_percent": hra_var.get(),
        "medical_allowance": medical_var.get(),
        "transport_allowance": transport_var.get(),
        "employee_type": emp_type_var.get(),
        "shift_allowance": shift_allowance_var.get() if emp_type_var.get() == "Regular" else 0
    }
    with open(SETTINGS_FILE, "w") as file:
        json.dump(settings, file, indent=4)
    update_salary_display()

# Function to calculate salary based on settings
def calculate_salary():
    settings = load_settings()
    basic_pay = 5000
    grade_pay = 1300  # Fixed, no setting
    da_amount = (settings["da_percent"] / 100) * basic_pay
    hra_amount = (settings["hra_percent"] / 100) * basic_pay
    total_salary = (
        basic_pay + grade_pay +
        da_amount +
        hra_amount +
        settings["medical_allowance"] +
        settings["transport_allowance"] +
        (settings["shift_allowance"] if settings["employee_type"] == "Regular" else 0)
    )
    
    return {
        "Basic Pay": (basic_pay, "blue"),  # Fixed Salary in Blue
        "Grade Pay": (grade_pay, "blue"),  
        "DA Amount": (da_amount, "orange"),  # DA & HRA (Linked to Basic Pay) in Orange
        "HRA Amount": (hra_amount, "orange"),  
        "Medical Allowance": (settings["medical_allowance"], "red"),  # Other Allowances in Red
        "Transport Allowance": (settings["transport_allowance"], "red"),  
        "Shift Allowance": ((settings["shift_allowance"] if settings["employee_type"] == "Regular" else 0), "blue"),
        "Total Salary": (total_salary, "green")  # Total Salary Highlighted
    }

# Function to update salary display in Home Tab
def update_salary_display():
    salary_details = calculate_salary()
    
    # Update labels with the new salary values
    for i, (key, (value, color)) in enumerate(salary_details.items()):
        salary_labels[i].config(text=f"{key}:", anchor="w", fg=color)  
        salary_values[i].config(text=f"₹{value:.2f}", anchor="e", fg=color)  

    # Highlight Total Salary
    salary_values[7].config(font=("Arial", 14, "bold"))

# Load settings at startup
settings = load_settings()

# Create the main Tkinter window
root = tk.Tk()
root.title("plus2net.com Salary Calculator with JSON Settings")
root.geometry("500x450")

# Create a Notebook (Tabs)
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)

### --- Home Tab (Salary Display) ---
home_frame = ttk.Frame(notebook)
notebook.add(home_frame, text="Salary Breakdown")

# Create Labels for Salary Breakdown
salary_labels = []
salary_values = []
for i in range(8):  
    label = tk.Label(home_frame, text="", font=("Arial", 11), width=18, anchor="w")
    label.grid(row=i, column=0, padx=30, pady=5)
    salary_labels.append(label)

    value = tk.Label(home_frame, text="", font=("Arial", 11, "bold"), width=12, anchor="e")
    value.grid(row=i, column=1, padx=1, pady=5)
    salary_values.append(value)

update_salary_display()

### --- Settings Tab ---
settings_frame = tk.Frame(notebook, bg="#e0e0e0")  # Light grey background
notebook.add(settings_frame, text="Settings")

# Header Label
tk.Label(settings_frame, text="Settings", font=("Arial", 16, "bold"), bg="#e0e0e0", fg="black").grid(row=0, column=0, columnspan=3, pady=10)

# DA Percentage (Slider) - Matching Colors
tk.Label(settings_frame, text="DA Percentage:", font=("Arial", 12), bg="#e0e0e0", fg="orange").grid(row=1, column=0, sticky="w", padx=10, pady=20)
da_var = tk.IntVar(value=settings["da_percent"])
tk.Scale(settings_frame, from_=0, to=100, orient="horizontal", variable=da_var, bg="#d0f0c0", length=300).grid(row=1, column=1, columnspan=2, sticky="w")

# HRA Percentage (Slider) - Matching Colors
tk.Label(settings_frame, text="HRA Percentage:", font=("Arial", 12), bg="#e0e0e0", fg="orange").grid(row=2, column=0, sticky="w", padx=10, pady=20)
hra_var = tk.IntVar(value=settings["hra_percent"])
tk.Scale(settings_frame, from_=0, to=100, orient="horizontal", variable=hra_var, bg="#d0f0c0", length=300).grid(row=2, column=1, columnspan=2, sticky="w")

# Medical Allowance (Spinbox)
tk.Label(settings_frame, text="Medical Allowance:", font=("Arial", 12), bg="#e0e0e0", fg="red").grid(row=3, column=0, sticky="w", padx=10, pady=5)
medical_var = tk.IntVar(value=settings["medical_allowance"])
tk.Spinbox(settings_frame, from_=0, to=1000, textvariable=medical_var, width=5).grid(row=3, column=1, sticky="w")

# Transport Allowance (Spinbox)
tk.Label(settings_frame, text="Transport Allowance:", font=("Arial", 12), bg="#e0e0e0", fg="red").grid(row=4, column=0, sticky="w", padx=10, pady=5)
transport_var = tk.IntVar(value=settings["transport_allowance"])
tk.Spinbox(settings_frame, from_=0, to=1000, textvariable=transport_var, width=5).grid(row=4, column=1, sticky="w")

# Employee Type (Radiobutton)
tk.Label(settings_frame, text="Employee Type:", font=("Arial", 12), bg="#e0e0e0", fg="black").grid(row=5, column=0, sticky="w", padx=10, pady=15)
emp_type_var = tk.StringVar(value=settings["employee_type"])
tk.Radiobutton(settings_frame, text="Regular", variable=emp_type_var, value="Regular", bg="#e0e0e0").grid(row=5, column=1, sticky="w")
tk.Radiobutton(settings_frame, text="Contract", variable=emp_type_var, value="Contract", bg="#e0e0e0").grid(row=5, column=2, sticky="w")

tk.Label(settings_frame, text="Shift Allowance:", font=("Arial", 12), bg="#e0e0e0", fg="blue").grid(row=6, column=0, sticky="w", padx=10, pady=5)
shift_allowance_var = tk.IntVar(value=settings["shift_allowance"])
tk.Spinbox(settings_frame, from_=0, to=1000, textvariable=shift_allowance_var, width=5).grid(row=6, column=1, sticky="w")

# Save Button
save_button = tk.Button(settings_frame, text="Save Settings", font=("Arial", 12, "bold"), command=save_settings, bg="blue", fg="white")
save_button.grid(row=7, column=0, columnspan=3, pady=10)

# Run Tkinter event loop
root.mainloop()

7. Conclusion

This tutorial provides a fully functional Tkinter settings page using JSON for persistence. Try modifying different values in the settings tab and watch real-time updates!

Payroll Management App Json data viewer by using Treeview
Compare saving settings in Database vs Json file

Subscribe to our YouTube Channel here


Subscribe

* indicates required
Subscribe to plus2net

    plus2net.com







    Python Video Tutorials
    Python SQLite Video Tutorials
    Python MySQL Video Tutorials
    Python Tkinter Video Tutorials
    We use cookies to improve your browsing experience. . Learn more
    HTML MySQL PHP JavaScript ASP Photoshop Articles FORUM . Contact us
    ©2000-2024 plus2net.com All rights reserved worldwide Privacy Policy Disclaimer