主要功能用于http或者https网站二维码生成,中心图片可自定义,python完整代码绝对干货需要的直接复制代码二次开发。 import tkinter as tk from tkinter import ttk, filedialog, messagebox import qrcode from PIL import Image, ImageTk, ImageDraw import os class QRGeneratorApp: def __init__(self, root): self.root = root self.root.title("千花二维码生成器") self.root.geometry("490x500") self.root.resizable(False, False)
self.protocol_var = tk.StringVar() self.protocol_var.trace_add('write', self.toggle_url_entry)
self.setup_ui() self.qr_image = None self.logo_image = None
def setup_ui(self): main_frame = tk.Frame(self.root, padx=15, pady=15) main_frame.pack(fill=tk.BOTH, expand=True)
# 协议选择区域(红色必选提示) protocol_frame = tk.Frame(main_frame) protocol_frame.pack(fill=tk.X, pady=3)
tk.Label(protocol_frame, text="1. 选择协议", font=('Arial', 9)).pack(side=tk.LEFT) tk.Label(protocol_frame, text="(必选)", fg="red", font=('Arial', 9)).pack(side=tk.LEFT)
protocol_btn_frame = tk.Frame(main_frame) protocol_btn_frame.pack(fill=tk.X, pady=3)
ttk.Radiobutton(protocol_btn_frame, text="HTTP", variable=self.protocol_var, value="http://").pack(side=tk.LEFT, padx=5) ttk.Radiobutton(protocol_btn_frame, text="HTTPS", variable=self.protocol_var, value="https://").pack(side=tk.LEFT, padx=5)
# 网址输入区域 url_frame = tk.LabelFrame(main_frame, text="2. 输入网址 (例如:www.mrnsht.com)", padx=8, pady=8) url_frame.pack(fill=tk.X, pady=5)
self.url_entry = tk.Entry(url_frame, state='disabled') self.url_entry.pack(fill=tk.X)
# Logo选择区域 logo_frame = tk.LabelFrame(main_frame, text="3. 添加中心图 (可选)", padx=8, pady=8) logo_frame.pack(fill=tk.X, pady=5)
btn_frame = tk.Frame(logo_frame) btn_frame.pack(fill=tk.X)
self.logo_btn = ttk.Button(btn_frame, text="选择图片...", command=self.select_logo) self.logo_btn.pack(side=tk.LEFT, padx=3)
self.logo_label = tk.Label(btn_frame, text="未选择", fg="gray") self.logo_label.pack(side=tk.LEFT)
# 按钮区域 action_frame = tk.Frame(main_frame) action_frame.pack(pady=8)
self.generate_btn = ttk.Button(action_frame, text="生成二维码", command=self.generate_qr) self.generate_btn.pack(side=tk.LEFT, padx=5)
self.save_btn = ttk.Button(action_frame, text="保存二维码", command=self.save_image, state=tk.DISABLED) self.save_btn.pack(side=tk.LEFT, padx=5)
# 预览区域 self.preview_frame = tk.LabelFrame(main_frame, text="二维码预览", padx=8, pady=8) self.preview_frame.pack(fill=tk.BOTH, expand=True)
self.canvas = tk.Canvas(self.preview_frame, bg='white', highlightthickness=0) self.canvas.pack(fill=tk.BOTH, expand=True)
def toggle_url_entry(self, *args): if self.protocol_var.get(): self.url_entry.config(state='normal') else: self.url_entry.config(state='disabled') self.url_entry.delete(0, tk.END)
def select_logo(self): filetypes = [('图片文件', '*.png *.jpg *.jpeg'), ('所有文件', '*.*')] filepath = filedialog.askopenfilename(title="选择Logo图片", filetypes=filetypes)
if filepath: try: self.logo_image = Image.open(filepath) self.logo_label.config(text=os.path.basename(filepath), fg="green") except Exception as e: messagebox.showerror("错误", f"图片加载失败: {str(e)}") self.logo_label.config(text="无效图片", fg="red")
def generate_qr(self): if not self.protocol_var.get(): messagebox.showwarning("提示", "请先选择协议类型") return
url = self.url_entry.get().strip() if not url: messagebox.showwarning("提示", "请输入网站地址") return
full_url = self.protocol_var.get() + url
try: qr = qrcode.QRCode( version=5, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=8, border=3, ) qr.add_data(full_url) qr.make(fit=True)
self.qr_image = qr.make_image(fill_color="black", back_color="white").convert('RGB')
if self.logo_image: logo_size = min(self.qr_image.size) // 4 logo = self.logo_image.resize((logo_size, logo_size), Image.LANCZOS)
mask = Image.new('L', (logo_size, logo_size), 0) mask_draw = ImageDraw.Draw(mask) mask_draw.ellipse((0, 0, logo_size, logo_size), fill=255)
pos = ( (self.qr_image.size[0] - logo_size) // 2, (self.qr_image.size[1] - logo_size) // 2 ) self.qr_image.paste(logo, pos, mask)
self.display_image() self.save_btn.config(state=tk.NORMAL)
except Exception as e: messagebox.showerror("错误", f"生成失败: {str(e)}") self.save_btn.config(state=tk.DISABLED)
def display_image(self): self.canvas.delete("all") canvas_width = self.canvas.winfo_width() canvas_height = self.canvas.winfo_height()
display_size = min(canvas_width, canvas_height) - 20 if display_size <= 0: return
img = self.qr_image.resize((display_size, display_size), Image.LANCZOS) img_tk = ImageTk.PhotoImage(img)
self.canvas.image = img_tk self.canvas.create_image( canvas_width//2, canvas_height//2, image=img_tk, anchor=tk.CENTER )
def save_image(self): if not self.qr_image: return
filepath = filedialog.asksaveasfilename( defaultextension=".png", filetypes=[("PNG图片", "*.png"), ("JPEG图片", "*.jpg"), ("所有文件", "*.*")], initialfile="qrcode.png" )
if filepath: try: self.qr_image.save(filepath) messagebox.showinfo("保存成功", f"二维码已保存到:\n{os.path.abspath(filepath)}") except Exception as e: messagebox.showerror("保存失败", f"错误: {str(e)}") if __name__ == "__main__": root = tk.Tk() app = QRGeneratorApp(root) root.mainloop() |