DEV Community

Mate Technologies
Mate Technologies

Posted on

🧮 Building a Binary Decimal Converter Pro with Python & Tkinter

In this tutorial, we’ll build a modern GUI app in Python that:

Converts binary → decimal

Supports single and batch conversion

Detects invalid binaries

Shows live statistics

Supports dark mode

Can open/save .txt files

No advanced Tkinter knowledge required—everything is explained step by step.

🛠️ Prerequisites

Make sure you have:

Python 3.9+

Basic Python knowledge

Tkinter (comes bundled with Python)

sv-ttk for modern theming

Install sv-ttk:

pip install sv-ttk

1️⃣ Imports & Dependencies

We start by importing everything we’ll need.

import sys
import os
import threading
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import sv_ttk
Enter fullscreen mode Exit fullscreen mode

Why these?

tkinter / ttk → GUI widgets

threading → delayed updates (prevents UI freezing)

filedialog & messagebox → file handling and alerts

sv_ttk → modern light/dark themes

2️⃣ Helper Functions
Resource Path Helper (for PyInstaller support)

def resource_path(file_name):
    base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, file_name)
Enter fullscreen mode Exit fullscreen mode

This ensures assets load correctly whether the app is:

Run normally

Packaged as an .exe

Status Bar Helper

def set_status(msg):
    status_var.set(msg)
    root.update_idletasks()
Enter fullscreen mode Exit fullscreen mode

This updates the status bar without freezing the UI.

3️⃣ App Window Setup

root = tk.Tk()
root.title("Binary → Decimal Converter Pro")
root.geometry("1200x680")
sv_ttk.set_theme("light")
Enter fullscreen mode Exit fullscreen mode

We:

Create the main window

Set a title and size

Apply a modern light theme

4️⃣ Global State Variables

Tkinter uses special variable classes to auto-update UI elements.

dark_mode_var = tk.BooleanVar(value=False)
binary_var = tk.StringVar()
decimal_var = tk.StringVar(value="0")
Enter fullscreen mode Exit fullscreen mode

Statistics variables

stats_vars = {
    "total_binaries": tk.StringVar(value="0"),
    "valid": tk.StringVar(value="0"),
    "invalid": tk.StringVar(value="0"),
    "sum": tk.StringVar(value="0"),
}
Enter fullscreen mode Exit fullscreen mode

5️⃣ Dark Mode Toggle

def toggle_theme():
    style.theme_use("clam")
    bg = "#2E2E2E" if dark_mode_var.get() else "#FFFFFF"
    fg = "white" if dark_mode_var.get() else "black"

    root.configure(bg=bg)

    for w in ["TFrame", "TLabel", "TLabelframe", "TLabelframe.Label", "TCheckbutton"]:
        style.configure(w, background=bg, foreground=fg)
Enter fullscreen mode Exit fullscreen mode

What this does:

Switches background & text colors

Updates all major ttk widgets

Keeps the UI readable in both modes

6️⃣ Single Binary Conversion Logic

def convert_single_binary():
    bin_str = binary_var.get().strip()
Enter fullscreen mode Exit fullscreen mode

Validate input

    if not bin_str:
        decimal_var.set("0")
        set_status("Enter a binary number")
        return
Enter fullscreen mode Exit fullscreen mode

Reject invalid binaries

    if not all(c in "01" for c in bin_str):
        decimal_var.set("Error")
        set_status("Invalid binary number")
        return
Enter fullscreen mode Exit fullscreen mode

Convert safely

    decimal_var.set(str(int(bin_str, 2)))
    set_status(f"Converted {bin_str} → {decimal_var.get()}")
Enter fullscreen mode Exit fullscreen mode

7️⃣ Batch Conversion Logic

def convert_batch():
    content = batch_text.get("1.0", tk.END).strip().splitlines()
Enter fullscreen mode Exit fullscreen mode

Track results

    valid_count = 0
    invalid_count = 0
    total_sum = 0
    results = []
Enter fullscreen mode Exit fullscreen mode

Process each line

    for line in content:
        if all(c in "01" for c in line):
            dec = int(line, 2)
            results.append(f"{line} → {dec}")
            valid_count += 1
            total_sum += dec
        else:
            results.append(f"{line} → Invalid")
            invalid_count += 1
Enter fullscreen mode Exit fullscreen mode

Update UI & stats

    batch_text.delete("1.0", tk.END)
    batch_text.insert("1.0", "\n".join(results))

    stats_vars["total_binaries"].set(len(content))
    stats_vars["valid"].set(valid_count)
    stats_vars["invalid"].set(invalid_count)
    stats_vars["sum"].set(total_sum)
Enter fullscreen mode Exit fullscreen mode

8️⃣ Delayed Auto-Conversion (Smooth UX)

Instead of converting on every keystroke, we add a short delay.

def delayed_single_convert(event=None):
    threading.Timer(0.1, convert_single_binary).start()

def delayed_batch_convert(event=None):
    threading.Timer(0.2, convert_batch).start()
Enter fullscreen mode Exit fullscreen mode

This keeps the UI responsive.

9️⃣ File Open & Save
Open .txt file

def open_file():
    path = filedialog.askopenfilename(filetypes=[("Text Files", "*.txt")])

    with open(path, "r", encoding="utf-8") as f:
        batch_text.insert("1.0", f.read())
Enter fullscreen mode Exit fullscreen mode

Save results

def save_file():
    path = filedialog.asksaveasfilename(defaultextension=".txt")

    with open(path, "w", encoding="utf-8") as f:
        f.write(batch_text.get("1.0", tk.END))
Enter fullscreen mode Exit fullscreen mode

🔟 Main UI Layout
Title

ttk.Label(main, text="Binary → Decimal Converter Pro",
          font=("Segoe UI", 20, "bold")).pack()
Enter fullscreen mode Exit fullscreen mode

Single Conversion Section

input_entry = ttk.Entry(single_frame, textvariable=binary_var)
input_entry.bind("<KeyRelease>", delayed_single_convert)
Enter fullscreen mode Exit fullscreen mode

Batch Conversion Textbox

batch_text = tk.Text(batch_frame, height=5)
batch_text.bind("<KeyRelease>", delayed_batch_convert)
Enter fullscreen mode Exit fullscreen mode

Statistics Grid

for i, (label, var) in enumerate(stats_vars.items()):
    ttk.Label(stats_frame, text=label.title()).grid(row=0, column=i*2)
    ttk.Label(stats_frame, textvariable=var).grid(row=0, column=i*2+1)
Enter fullscreen mode Exit fullscreen mode

1️⃣1️⃣ Action Buttons

ttk.Button(actions, text="📂 Open", command=open_file).pack(side="left")
ttk.Button(actions, text="💾 Save", command=save_file).pack(side="left")
ttk.Button(actions, text="🧹 Clear", command=clear_all).pack(side="left")
ttk.Button(actions, text="❓ Help", command=show_help).pack(side="left")
Enter fullscreen mode Exit fullscreen mode

1️⃣2️⃣ Run the App

root.mainloop()
Enter fullscreen mode Exit fullscreen mode

This starts the Tkinter event loop—and your app is live 🎉

🚀 Final Thoughts

You now have:

A polished Tkinter GUI

Live conversion logic

Batch processing

Dark mode

File support

💡 Ideas to extend it

Export CSV

Copy to clipboard

Add hex / octal support

Package with PyInstaller

Binary → Decimal Converter Pro

Top comments (0)