#!/usr/bin/env python3 """ DeadQR - A simple GUI tool to create and customize QR codes """ import tkinter as tk from tkinter import ttk, filedialog, messagebox, colorchooser from PIL import Image, ImageTk import qrcode from qrcode.image.styledpil import StyledPilImage from qrcode.image.styles.moduledrawers import RoundedModuleDrawer, CircleModuleDrawer, SquareModuleDrawer import io class QRCodeGenerator: def __init__(self, root): self.root = root self.root.title("DeadQR") self.root.geometry("800x720") self.root.resizable(False, False) # QR code settings self.qr_image = None self.fg_color = "#000000" self.bg_color = "#FFFFFF" self.setup_ui() def setup_ui(self): # Main container main_frame = ttk.Frame(self.root, padding="10") main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # Title title_label = ttk.Label(main_frame, text="DeadQR", font=("Arial", 24, "bold")) title_label.grid(row=0, column=0, columnspan=2, pady=10) subtitle_label = ttk.Label(main_frame, text="Advanced QR Code Generator", font=("Arial", 10, "italic")) subtitle_label.grid(row=1, column=0, columnspan=2, pady=(0, 10)) # Input section input_frame = ttk.LabelFrame(main_frame, text="Content", padding="10") input_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5) ttk.Label(input_frame, text="Enter text or URL:").grid(row=0, column=0, sticky=tk.W) self.text_input = tk.Text(input_frame, height=4, width=60, wrap=tk.WORD) self.text_input.grid(row=1, column=0, pady=5) self.text_input.bind('', lambda e: self.generate_qr()) # Settings section settings_frame = ttk.LabelFrame(main_frame, text="Settings", padding="10") settings_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5) # Size ttk.Label(settings_frame, text="Size:").grid(row=0, column=0, sticky=tk.W, padx=5) self.size_var = tk.IntVar(value=10) size_slider = ttk.Scale(settings_frame, from_=5, to=20, orient=tk.HORIZONTAL, variable=self.size_var, command=lambda e: self.generate_qr()) size_slider.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=5) self.size_label = ttk.Label(settings_frame, text="10") self.size_label.grid(row=0, column=2, padx=5) # Error correction ttk.Label(settings_frame, text="Error Correction:").grid(row=1, column=0, sticky=tk.W, padx=5, pady=5) self.error_var = tk.StringVar(value="M") error_combo = ttk.Combobox(settings_frame, textvariable=self.error_var, values=["L (7%)", "M (15%)", "Q (25%)", "H (30%)"], state="readonly", width=15) error_combo.grid(row=1, column=1, sticky=tk.W, padx=5, pady=5) error_combo.bind('<>', lambda e: self.generate_qr()) # Style ttk.Label(settings_frame, text="Style:").grid(row=2, column=0, sticky=tk.W, padx=5, pady=5) self.style_var = tk.StringVar(value="Square") style_combo = ttk.Combobox(settings_frame, textvariable=self.style_var, values=["Square", "Rounded", "Circle"], state="readonly", width=15) style_combo.grid(row=2, column=1, sticky=tk.W, padx=5, pady=5) style_combo.bind('<>', lambda e: self.generate_qr()) # Colors color_frame = ttk.Frame(settings_frame) color_frame.grid(row=3, column=0, columnspan=3, pady=10) ttk.Label(color_frame, text="Foreground:").grid(row=0, column=0, padx=5) self.fg_btn = tk.Button(color_frame, bg=self.fg_color, width=10, command=lambda: self.choose_color('fg')) self.fg_btn.grid(row=0, column=1, padx=5) ttk.Label(color_frame, text="Background:").grid(row=0, column=2, padx=5) self.bg_btn = tk.Button(color_frame, bg=self.bg_color, width=10, command=lambda: self.choose_color('bg')) self.bg_btn.grid(row=0, column=3, padx=5) # Preview section preview_frame = ttk.LabelFrame(main_frame, text="Preview", padding="10") preview_frame.grid(row=4, column=0, columnspan=2, pady=10) self.preview_label = ttk.Label(preview_frame, text="Enter text to generate QR code", relief=tk.SUNKEN, width=50) self.preview_label.grid(row=0, column=0, padx=10, pady=10) # Buttons button_frame = ttk.Frame(main_frame) button_frame.grid(row=5, column=0, columnspan=2, pady=10) ttk.Button(button_frame, text="Generate QR Code", command=self.generate_qr).grid(row=0, column=0, padx=5) ttk.Button(button_frame, text="Save as PNG", command=self.save_qr).grid(row=0, column=1, padx=5) ttk.Button(button_frame, text="Clear", command=self.clear_all).grid(row=0, column=2, padx=5) # Update size label when slider moves self.size_var.trace('w', self.update_size_label) def update_size_label(self, *args): self.size_label.config(text=str(self.size_var.get())) def choose_color(self, color_type): color = colorchooser.askcolor(title="Choose color") if color[1]: if color_type == 'fg': self.fg_color = color[1] self.fg_btn.config(bg=self.fg_color) else: self.bg_color = color[1] self.bg_btn.config(bg=self.bg_color) self.generate_qr() def get_error_correction(self): error_map = { "L (7%)": qrcode.constants.ERROR_CORRECT_L, "M (15%)": qrcode.constants.ERROR_CORRECT_M, "Q (25%)": qrcode.constants.ERROR_CORRECT_Q, "H (30%)": qrcode.constants.ERROR_CORRECT_H } return error_map.get(self.error_var.get(), qrcode.constants.ERROR_CORRECT_M) def get_style_drawer(self): style_map = { "Square": SquareModuleDrawer(), "Rounded": RoundedModuleDrawer(), "Circle": CircleModuleDrawer() } return style_map.get(self.style_var.get(), SquareModuleDrawer()) def generate_qr(self): text = self.text_input.get("1.0", tk.END).strip() if not text: self.preview_label.config(image='', text="Enter text to generate QR code") self.qr_image = None return try: # Create QR code qr = qrcode.QRCode( version=1, error_correction=self.get_error_correction(), box_size=self.size_var.get(), border=4, ) qr.add_data(text) qr.make(fit=True) # Generate image with style self.qr_image = qr.make_image( image_factory=StyledPilImage, module_drawer=self.get_style_drawer(), fill_color=self.fg_color, back_color=self.bg_color ) # Display preview self.display_preview() except Exception as e: messagebox.showerror("Error", f"Failed to generate QR code: {str(e)}") def display_preview(self): if self.qr_image: # Resize for preview preview_size = (300, 300) preview_img = self.qr_image.copy() preview_img.thumbnail(preview_size, Image.Resampling.LANCZOS) # Convert to PhotoImage photo = ImageTk.PhotoImage(preview_img) self.preview_label.config(image=photo, text="") self.preview_label.image = photo # Keep reference def save_qr(self): if not self.qr_image: messagebox.showwarning("No QR Code", "Please generate a QR code first!") return file_path = filedialog.asksaveasfilename( defaultextension=".png", filetypes=[("PNG files", "*.png"), ("All files", "*.*")] ) if file_path: try: self.qr_image.save(file_path) messagebox.showinfo("Success", f"QR code saved to:\n{file_path}") except Exception as e: messagebox.showerror("Error", f"Failed to save QR code: {str(e)}") def clear_all(self): self.text_input.delete("1.0", tk.END) self.preview_label.config(image='', text="Enter text to generate QR code") self.qr_image = None self.size_var.set(10) self.error_var.set("M") self.style_var.set("Square") self.fg_color = "#000000" self.bg_color = "#FFFFFF" self.fg_btn.config(bg=self.fg_color) self.bg_btn.config(bg=self.bg_color) def main(): root = tk.Tk() app = QRCodeGenerator(root) root.mainloop() if __name__ == "__main__": main()