[Python] 纯文本查看 复制代码
import qrcode
import tkinter as tk
from tkinter import filedialog, colorchooser, messagebox, ttk
import os
from PIL import Image, ImageTk
class QRCodeGenerator:
def __init__(self, root):
self.root = root
self.root.title("鄂J-Monkey二维码生成器-[url=https://www.ltxit.com/]https://www.ltxit.com/[/url]")
self.root.geometry("600x600")
self.root.resizable(True, True)
self.root.configure(bg="#f0f0f0")
# 设置中文字体
self.font = ("SimHei", 10)
# 创建主框架
self.main_frame = ttk.Frame(root, padding="20")
self.main_frame.pack(fill=tk.BOTH, expand=True)
# 输入类型选择
ttk.Label(self.main_frame, text="输入类型:", font=self.font).grid(row=0, column=0, sticky=tk.W, pady=5)
self.input_type = tk.StringVar(value="网址")
input_types = ["文本", "网址", "文件"]
self.type_combo = ttk.Combobox(self.main_frame, textvariable=self.input_type, values=input_types,
state="readonly", width=20)
self.type_combo.grid(row=0, column=1, sticky=tk.W, pady=5)
self.type_combo.bind("<<ComboboxSelected>>", self.on_input_type_changed)
# 输入框
ttk.Label(self.main_frame, text="输入内容:", font=self.font).grid(row=1, column=0, sticky=tk.W, pady=5)
self.input_text = tk.Text(self.main_frame, height=5, width=40, font=self.font)
self.input_text.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=5)
# 文件选择按钮
self.file_button = ttk.Button(self.main_frame, text="选择文件", command=self.select_file)
self.file_button.grid(row=1, column=2, sticky=tk.W, padx=5, pady=5)
self.file_path_var = tk.StringVar()
self.file_path_label = ttk.Label(self.main_frame, textvariable=self.file_path_var, font=("SimHei", 9),
foreground="blue")
self.file_path_label.grid(row=2, column=1, sticky=tk.W, pady=2)
# 二维码大小滑块
ttk.Label(self.main_frame, text="二维码大小:", font=self.font).grid(row=3, column=0, sticky=tk.W, pady=5)
self.size_var = tk.IntVar(value=128)
self.size_scale = ttk.Scale(self.main_frame, from_=100, to=600, variable=self.size_var, orient=tk.HORIZONTAL,
length=200)
self.size_scale.grid(row=3, column=1, sticky=tk.W, pady=5)
self.size_label = ttk.Label(self.main_frame, text="128", font=self.font, width=5)
self.size_label.grid(row=3, column=1, sticky=tk.E, pady=5)
self.size_scale.bind("<Motion>", self.update_size_label)
self.size_scale.bind("<ButtonRelease-1>", self.update_size_label)
# 容错级别选择
ttk.Label(self.main_frame, text="容错级别:", font=self.font).grid(row=4, column=0, sticky=tk.W, pady=5)
self.error_correction = tk.StringVar(value="中等")
error_levels = ["低", "中等", "高", "最高"]
self.error_combo = ttk.Combobox(self.main_frame, textvariable=self.error_correction, values=error_levels,
state="readonly", width=10)
self.error_combo.grid(row=4, column=1, sticky=tk.W, pady=5)
# 背景颜色选择
ttk.Label(self.main_frame, text="背景颜色:", font=self.font).grid(row=5, column=0, sticky=tk.W, pady=5)
self.bg_color_var = tk.StringVar(value="white")
self.bg_color_display = ttk.Label(self.main_frame, text=" ", background="white", relief=tk.SUNKEN,
borderwidth=1)
self.bg_color_display.grid(row=5, column=1, sticky=tk.W, padx=5, pady=5)
self.bg_color_button = ttk.Button(self.main_frame, text="选择颜色", command=self.choose_bg_color)
self.bg_color_button.grid(row=5, column=1, sticky=tk.E, padx=5, pady=5)
# 边框大小选择
ttk.Label(self.main_frame, text="边框大小:", font=self.font).grid(row=6, column=0, sticky=tk.W, pady=5)
self.border_var = tk.IntVar(value=1)
self.border_scale = ttk.Scale(self.main_frame, from_=0, to=10, variable=self.border_var, orient=tk.HORIZONTAL,
length=200)
self.border_scale.grid(row=6, column=1, sticky=tk.W, pady=5)
self.border_label = ttk.Label(self.main_frame, text="1", font=self.font, width=5)
self.border_label.grid(row=6, column=1, sticky=tk.E, pady=5)
self.border_scale.bind("<Motion>", self.update_border_label)
self.border_scale.bind("<ButtonRelease-1>", self.update_border_label)
# 生成按钮
self.generate_button = ttk.Button(self.main_frame, text="生成二维码", command=self.generate_qrcode,
style='Accent.TButton')
self.generate_button.grid(row=7, column=1, pady=10)
# 二维码显示区域
self.qr_frame = ttk.LabelFrame(self.main_frame, text="二维码预览", padding="10")
self.qr_frame.grid(row=8, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S), pady=10)
self.qr_frame.columnconfigure(0, weight=1)
self.qr_frame.rowconfigure(0, weight=1)
self.qr_label = ttk.Label(self.qr_frame)
self.qr_label.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 保存按钮
self.save_button = ttk.Button(self.main_frame, text="保存二维码", command=self.save_qrcode, state=tk.DISABLED)
self.save_button.grid(row=9, column=1, pady=5)
# 状态栏
self.status_var = tk.StringVar(value="就绪")
self.status_bar = ttk.Label(root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
# 配置列和行的权重,使界面可缩放
self.main_frame.columnconfigure(1, weight=1)
self.main_frame.rowconfigure(8, weight=1)
# 初始状态
self.current_image = None
self.on_input_type_changed(None)
def on_input_type_changed(self, event):
"""根据输入类型更改UI状态"""
input_type = self.input_type.get()
self.input_text.delete(1.0, tk.END)
self.file_path_var.set("")
if input_type == "文件":
self.input_text.config(state=tk.DISABLED)
self.file_button.config(state=tk.NORMAL)
self.status_var.set("请选择要生成二维码的文件")
else:
self.input_text.config(state=tk.NORMAL)
self.file_button.config(state=tk.DISABLED)
if input_type == "文本":
self.input_text.insert(tk.END, "请输入要生成二维码的文本...")
self.status_var.set("请输入要生成二维码的文本")
elif input_type == "网址":
self.input_text.insert(tk.END, "https://")
self.status_var.set("请输入要生成二维码的网址")
def select_file(self):
"""打开文件选择对话框"""
file_path = filedialog.askopenfilename()
if file_path:
self.file_path_var.set(file_path)
self.status_var.set(f"已选择文件: {os.path.basename(file_path)}")
def update_size_label(self, event):
"""更新大小标签显示"""
size = self.size_var.get()
self.size_label.config(text=str(size))
def update_border_label(self, event):
"""更新边框标签显示"""
border = self.border_var.get()
self.border_label.config(text=str(border))
def choose_bg_color(self):
"""选择背景颜色"""
color = colorchooser.askcolor(initialcolor=self.bg_color_var.get(), title="选择背景颜色")
if color[1]: # 如果用户选择了颜色
self.bg_color_var.set(color[1])
self.bg_color_display.config(background=color[1])
def get_error_correction_level(self):
"""获取对应的纠错级别"""
level_map = {
"低": qrcode.constants.ERROR_CORRECT_L,
"中等": qrcode.constants.ERROR_CORRECT_M,
"高": qrcode.constants.ERROR_CORRECT_Q,
"最高": qrcode.constants.ERROR_CORRECT_H
}
return level_map[self.error_correction.get()]
def generate_qrcode(self):
"""生成二维码"""
try:
input_type = self.input_type.get()
if input_type == "文件":
file_path = self.file_path_var.get()
if not file_path:
messagebox.showerror("错误", "请选择一个文件")
return
try:
with open(file_path, 'r', encoding='utf-8') as file:
data = file.read()
if len(data) == 0:
messagebox.showerror("错误", "文件内容为空")
return
except Exception as e:
messagebox.showerror("错误", f"无法读取文件: {str(e)}")
return
else:
data = self.input_text.get(1.0, tk.END).strip()
if not data:
messagebox.showerror("错误", "输入内容不能为空")
return
if input_type == "网址" and not data.startswith(('http://', 'https://')):
messagebox.showwarning("警告", "网址应当以 'http://' 或 'https://' 开头")
data = "https://" + data
# 生成二维码
qr = qrcode.QRCode(
version=1,
error_correction=self.get_error_correction_level(),
box_size=10,
border=self.border_var.get() # 使用用户设置的边框大小
)
qr.add_data(data)
qr.make(fit=True)
# 创建图片,使用用户选择的背景颜色
bg_color = self.bg_color_var.get()
img = qr.make_image(fill_color="black", back_color=bg_color)
# 调整图片大小
size = self.size_var.get()
img = img.resize((size, size), Image.LANCZOS)
# 显示二维码
self.current_image = ImageTk.PhotoImage(img)
self.qr_label.config(image=self.current_image)
self.save_button.config(state=tk.NORMAL)
self.status_var.set("二维码生成成功")
except Exception as e:
messagebox.showerror("错误", f"生成二维码失败: {str(e)}")
self.status_var.set("生成二维码失败")
def save_qrcode(self):
"""保存二维码图片"""
if self.current_image is None:
messagebox.showerror("错误", "没有生成的二维码可保存")
return
file_path = filedialog.asksaveasfilename(
defaultextension=".png",
filetypes=[("PNG 文件", "*.png"), ("JPEG 文件", "*.jpg"), ("所有文件", "*.*")]
)
if file_path:
try:
# 从 PhotoImage 获取原始的 PIL 图像并保存
img = self.current_image._PhotoImage__photo
img.write(file_path, format=os.path.splitext(file_path)[1][1:].upper())
self.status_var.set(f"二维码已保存至: {file_path}")
messagebox.showinfo("成功", f"二维码已成功保存至:\n{file_path}")
except Exception as e:
messagebox.showerror("错误", f"保存二维码失败: {str(e)}")
self.status_var.set("保存二维码失败")
if __name__ == "__main__":
root = tk.Tk()
# 设置主题
style = ttk.Style()
if 'clam' in style.theme_names():
style.theme_use('clam')
# 创建自定义样式
style.configure('Accent.TButton', font=("SimHei", 10, "bold"))
app = QRCodeGenerator(root)
root.mainloop()