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

Subhendu Mohapatra — author at plus2net
Subhendu Mohapatra

Author

🎥 Join me live on YouTube

Passionate about coding and teaching, I publish practical tutorials on PHP, Python, JavaScript, SQL, and web development. My goal is to make learning simple, engaging, and project‑oriented with real examples and source code.



Subscribe to our YouTube Channel here



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 Contact us
©2000-2025   plus2net.com   All rights reserved worldwide Privacy Policy Disclaimer