νλ‘κ·Έλ¨ μ΄λ¦
μ€λͺ
νλ‘κ·Έλ¨
1
2
ν둬ννΈ
νλ₯΄μλ
- νμ΄μ¬ νλ‘κ·Έλλ° νμ΅μ
μμ
- QR μ½λ μμ± νλ‘κ·Έλ¨ κ°λ°
λ§₯λ½
- μΈμ΄ : νμ΄μ¬
- λ²μ : 3.13
- ꡬ쑰 : GUI νλ‘κ·Έλ¨
- κΈ°λ₯
* QR μ½λ μμ±
* QR κ΄λ ¨ μ 보 μ
λ ₯ : QRμ½λ μ΄λ¦, QR μ½λ κ°, νμΌκ²½λ‘
* MySQL λ°μ΄ν°λ² μ΄μ€λ‘ QRμ½λ μ 보 κ΄λ¦¬
* QR μ½λ κ΄λ¦¬ : QRμ½λ μ΄λ¦ λ³κ²½, QRμ½λ μ 보 λ° μ΄λ―Έμ§ μμ
* QR μ½λ κ΄λ¦¬ λμ보λ : λ±λ‘λ QR μ½λ 리μ€νΈλ‘ νμΈ, μμ μμ μμ΄μ½ λ²νΌμΌλ‘ κ΄λ¦¬
* QR μ½λ μμ νλ©΄ : μ½λ μ΄λ¦ λ³κ²½, μμ λ²νΌ
* DB μ μ μ qr_code ν
μ΄λΈ μμ±
νμ
- QRμ½λ μ΄λ―Έμ§ νμ₯μ : png
- μ΄λ―Έμ§ νμΌ μ΄λ¦ : μ°μμΌ_μλΆμ΄_μ½λμ΄λ¦.png
- QR μ½λ μ 보 ν
μ΄λΈ
: qr_code
(no, id, name, value, path, created_at, updated_at)
(λ²νΈ, UUID, QRμ½λμ΄λ¦, μ½λ κ°, νμΌκ²½λ‘, λ±λ‘μΌμ, μμ μΌμ)
- db μ μ μ 보
* κ³μ : python
* λΉλ°λ²νΈ : 123456
* λ°μ΄ν°λ² μ΄μ€ : python
μμ
- "https://xn--pe5b27r.com/" λ₯Ό μ½λ κ°μΌλ‘ μ§μ νκ³
μν΄ μ¬μ΄νΈ λΌλ qrμ½λ μ΄λ¦μΌλ‘
c:/qrcode/νμΌλͺ
κ²½λ‘λ‘ μ μ₯
μΊλ²μ€ λͺ¨λλ‘ μλ΅
Plain Text
볡μ¬
μ€μΉ
pip install qrcode[pil] pillow mysql-connector-python
Bash
볡μ¬
DB ꡬμΆ
-- 1. μ¬μ©μ κ³μ μμ± (λΉλ°λ²νΈλ '123456')
CREATE USER 'python'@'localhost' IDENTIFIED BY '123456';
-- 2. λ°μ΄ν°λ² μ΄μ€κ° μλ€λ©΄ μμ±
CREATE DATABASE IF NOT EXISTS python DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 3. κΆν λΆμ¬ (qr_db μ λν λͺ¨λ κΆν)
GRANT ALL PRIVILEGES ON python.* TO 'python'@'localhost';
-- 4. λ³κ²½μ¬ν μ μ©
FLUSH PRIVILEGES;
SQL
볡μ¬
CREATE TABLE qr_code (
no INT AUTO_INCREMENT PRIMARY KEY,
id CHAR(36) NOT NULL UNIQUE, -- UUID
name VARCHAR(100) NOT NULL, -- QR μ½λ μ΄λ¦
value TEXT NOT NULL, -- QR μ½λμ λ΄κΈ΄ κ°
path VARCHAR(255) NOT NULL, -- μ΄λ―Έμ§ νμΌ μ μ₯ κ²½λ‘
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
SQL
볡μ¬
μ½λ
# QR μ½λ μμ± λ° κ΄λ¦¬ GUI νλ‘κ·Έλ¨
# μΈμ΄: Python 3.13
# GUI: tkinter
# QR μ½λ μμ±: qrcode
# DB: mysql-connector-python
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import qrcode
import os
import uuid
from datetime import datetime
import mysql.connector
# DB μ°κ²° μ€μ
# μ¬μ©μ: python, λΉλ°λ²νΈ: 123456
# DB μ΄λ¦μ κΈ°μ‘΄κ³Ό λμΌνκ² μ¬μ© (qr_code)
db_config = {
'host': 'localhost',
'user': 'python',
'password': '123456',
'database': 'python'
}
# DB μ°κ²° ν¨μ
def get_connection():
return mysql.connector.connect(**db_config)
# ν
μ΄λΈ μμ± ν¨μ (QR μ½λ ν
μ΄λΈμ΄ μμ κ²½μ° μμ±)
def create_table_if_not_exists():
conn = get_connection()
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS qr_code (
no INT AUTO_INCREMENT PRIMARY KEY,
id VARCHAR(36) NOT NULL,
name VARCHAR(100) NOT NULL,
value TEXT NOT NULL,
path TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL
);
""")
conn.commit()
cursor.close()
conn.close()
# νλ‘κ·Έλ¨ μμ μ ν
μ΄λΈ νμΈ λ° μμ±
create_table_if_not_exists()
# QR μ½λ μ μ₯ ν¨μ
def save_qr_to_db(qr_id, name, value, path):
conn = get_connection()
cursor = conn.cursor()
now = datetime.now()
cursor.execute("""
INSERT INTO qr_code (id, name, value, path, created_at, updated_at)
VALUES (%s, %s, %s, %s, %s, %s)
""", (qr_id, name, value, path, now, now))
conn.commit()
cursor.close()
conn.close()
# QR μ½λ μμ ν¨μ
def update_qr_name(qr_no, new_name):
conn = get_connection()
cursor = conn.cursor()
now = datetime.now()
cursor.execute("""
UPDATE qr_code SET name=%s, updated_at=%s WHERE no=%s
""", (new_name, now, qr_no))
conn.commit()
cursor.close()
conn.close()
# QR μ½λ μμ ν¨μ
def delete_qr(qr_no):
conn = get_connection()
cursor = conn.cursor()
cursor.execute("SELECT path FROM qr_code WHERE no=%s", (qr_no,))
result = cursor.fetchone()
if result:
try:
os.remove(result[0])
except:
pass
cursor.execute("DELETE FROM qr_code WHERE no=%s", (qr_no,))
conn.commit()
cursor.close()
conn.close()
# QR μ½λ μμ± ν¨μ
def generate_qr():
name = entry_name.get()
value = entry_value.get()
folder = entry_path.get()
if not (name and value and folder):
messagebox.showerror("μ
λ ₯ μ€λ₯", "λͺ¨λ νλλ₯Ό μ
λ ₯ν΄μ£ΌμΈμ.")
return
qr_id = str(uuid.uuid4())
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{timestamp}_{name}.png"
full_path = os.path.join(folder, filename)
img = qrcode.make(value)
img.save(full_path)
save_qr_to_db(qr_id, name, value, full_path)
messagebox.showinfo("μλ£", f"QR μ½λκ° μ μ₯λμμ΅λλ€: {full_path}")
refresh_dashboard()
# λμ보λ κ°±μ
def refresh_dashboard():
for row in tree.get_children():
tree.delete(row)
conn = get_connection()
cursor = conn.cursor()
cursor.execute("SELECT no, name, value, path FROM qr_code")
for (no, name, value, path) in cursor.fetchall():
tree.insert('', 'end', values=(no, name, value, path))
cursor.close()
conn.close()
# μ νλ νλͺ©μμ μμ
def on_edit():
selected = tree.focus()
if not selected:
messagebox.showwarning("μ ν μμ", "μμ ν QR μ½λλ₯Ό μ ννμΈμ.")
return
values = tree.item(selected, 'values')
qr_no = values[0]
new_name = simple_input("QR μ½λ μ΄λ¦ μμ ", "μ μ΄λ¦μ μ
λ ₯νμΈμ:", values[1])
if new_name:
update_qr_name(qr_no, new_name)
refresh_dashboard()
# μ νλ νλͺ© μμ
def on_delete():
selected = tree.focus()
if not selected:
messagebox.showwarning("μ ν μμ", "μμ ν QR μ½λλ₯Ό μ ννμΈμ.")
return
values = tree.item(selected, 'values')
qr_no = values[0]
if messagebox.askyesno("μμ νμΈ", "μ λ§ μμ νμκ² μ΅λκΉ?"):
delete_qr(qr_no)
refresh_dashboard()
# κ°λ¨ν μ
λ ₯μ°½ ν¨μ
def simple_input(title, prompt, default_value=''):
popup = tk.Toplevel()
popup.title(title)
popup.grab_set()
tk.Label(popup, text=prompt).pack(padx=10, pady=5)
input_var = tk.StringVar(value=default_value)
entry = ttk.Entry(popup, textvariable=input_var)
entry.pack(padx=10, pady=5)
entry.focus()
result = {'value': None}
def submit():
result['value'] = input_var.get()
popup.destroy()
ttk.Button(popup, text="νμΈ", command=submit).pack(pady=5)
popup.wait_window()
return result['value']
# GUI μ€μ
root = tk.Tk()
root.title("QR μ½λ μμ± λ° κ΄λ¦¬")
root.geometry("800x600")
frame_input = ttk.LabelFrame(root, text="QR μ½λ μ 보 μ
λ ₯")
frame_input.pack(fill="x", padx=10, pady=5)
entry_name = ttk.Entry(frame_input, width=50)
entry_value = ttk.Entry(frame_input, width=50)
entry_path = ttk.Entry(frame_input, width=50)
btn_browse = ttk.Button(frame_input, text="ν΄λ μ ν", command=lambda: entry_path.insert(0, filedialog.askdirectory() + '/'))
entry_name.grid(row=0, column=1, padx=5, pady=5)
entry_value.grid(row=1, column=1, padx=5, pady=5)
entry_path.grid(row=2, column=1, padx=5, pady=5)
btn_browse.grid(row=2, column=2, padx=5)
tt_label = ["QR μ½λ μ΄λ¦:", "QR μ½λ κ°:", "μ μ₯ κ²½λ‘:"]
for i, txt in enumerate(tt_label):
ttk.Label(frame_input, text=txt).grid(row=i, column=0, sticky="e", padx=5, pady=5)
btn_generate = ttk.Button(root, text="QR μ½λ μμ±", command=generate_qr)
btn_generate.pack(pady=10)
frame_dashboard = ttk.LabelFrame(root, text="QR μ½λ λμ보λ")
frame_dashboard.pack(fill="both", expand=True, padx=10, pady=10)
cols = ("λ²νΈ", "μ΄λ¦", "κ°", "νμΌ κ²½λ‘")
tree = ttk.Treeview(frame_dashboard, columns=cols, show='headings')
for col in cols:
tree.heading(col, text=col)
tree.column(col, width=150)
tree.pack(fill="both", expand=True)
btn_edit = ttk.Button(root, text="QR μ½λ μ΄λ¦ μμ ", command=on_edit)
btn_delete = ttk.Button(root, text="QR μ½λ μμ ", command=on_delete)
btn_edit.pack(pady=5)
btn_delete.pack(pady=5)
refresh_dashboard()
root.mainloop()
Python
볡μ¬