Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
```
# Python
__pycache__/
*.pyc
*.pyo
*.pyd

# Dependencies
.venv/
venv/
env/
.env
.env.local
.env.*

# Logs and temp files
*.log
*.tmp

# Editors
.vscode/
.idea/
*.swp
*.swo

# Build and distribution
dist/
build/
*.egg-info/

# Coverage
.coverage
coverage/
htmlcov/

# Testing
.pytest_cache/
.mypy_cache/
```
170 changes: 170 additions & 0 deletions python/README_GUI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# QR Code Generator GUI - Hướng dẫn sử dụng

## Tổng quan

Ứng dụng GUI tạo mã QR với các tính năng:
- ✅ **4 ngôn ngữ**: English, Tiếng Việt, 日本語,中文
- ✅ **2 chủ đề**: Light Theme & Dark Theme
- ✅ **Xuất SVG** với tùy chỉnh màu sắc và tỷ lệ
- ✅ **Giao diện hiện đại**, dễ sử dụng

## Yêu cầu hệ thống

```bash
# Python 3.6+
# Tkinter (thường đi kèm với Python)
```

## Cài đặt

### Trên Ubuntu/Debian:
```bash
sudo apt-get install python3-tk
```

### Trên Fedora:
```bash
sudo dnf install python3-tkinter
```

### Trên macOS:
```bash
brew install python-tk
```

### Trên Windows:
Tkinter thường được cài đặt sẵn với Python.

## Chạy ứng dụng

```bash
cd /workspace/python
python qrcodegen_gui.py
```

## Tính năng chính

### 1. Đa ngôn ngữ (4 languages)
- **English** - Tiếng Anh
- **Tiếng Việt** - Vietnamese
- **日本語** - Japanese
- **中文** - Chinese

Chuyển đổi ngôn ngữ qua menu `Language` hoặc phím tắt.

### 2. Chủ đề sáng/tối (Light/Dark Theme)
- **Light Theme**: Giao diện sáng, phù hợp ban ngày
- **Dark Theme**: Giao diện tối, bảo vệ mắt, phù hợp ban đêm

Chuyển đổi qua:
- Menu `View > Light/Dark Theme`
- Nút toggle góc phải màn hình
- Phím tắt

### 3. Tùy chỉnh mã QR
- **Error Correction**: L, M, Q, H (từ thấp đến cao)
- **Border**: Độ rộng viền (0-20 modules)
- **Scale**: Tỷ lệ phóng to (1-50 pixels/module)
- **Foreground Color**: Màu前景 (mặc định: đen)
- **Background Color**: Màu nền (mặc định: trắng)

### 4. Xuất file
- **Save as SVG**: Lưu file vector SVG
- **Copy SVG**: Sao chép mã SVG vào clipboard
- **Clear**: Xóa toàn bộ để tạo mới

## Cấu trúc code

```
qrcodegen_gui.py
├── LANGUAGES # Dictionary chứa bản dịch 4 ngôn ngữ
├── LIGHT_THEME # Cấu hình màu light theme
├── DARK_THEME # Cấu hình màu dark theme
└── QRCodeGenerator # Class chính
├── __init__() # Khởi tạo giao diện
├── _create_menu() # Tạo menu bar
├── _create_widgets() # Tạo widgets
├── _apply_theme() # Áp dụng theme
├── _update_language() # Cập nhật ngôn ngữ
├── generate_qr() # Tạo mã QR
├── save_svg() # Lưu file SVG
└── ...
```

## API Usage

### Tạo QR Code với SVG:

```python
from qrcodegen import QrCode
from qrcodegen_gui import QRCodeGenerator

# Tạo instance
generator = QRCodeGenerator(root=None) # root=None cho headless mode

# Tạo QR Code
qr = QrCode.encode_text("Hello, World!", QrCode.Ecc.MEDIUM)

# Tạo SVG string
svg = generator.to_svg_str(
qr,
border=4,
scale=10,
foreground_color="#000080", # Xanh dương
background_color="#FFFFFF" # Trắng
)

# Lưu vào file
with open("qrcode.svg", "w") as f:
f.write(svg)
```

## Screenshots

### Light Theme (English)
- Giao diện sáng, sạch sẽ
- Menu đầy đủ chức năng
- Preview QR Code realtime

### Dark Theme (Tiếng Việt)
- Giao diện tối, dịu mắt
- Full tiếng Việt
- Tương phản tốt

## Phím tắt

| Phím | Chức năng |
|------|-----------|
| `Ctrl+S` | Lưu file SVG |
| `Ctrl+Q` | Thoát ứng dụng |

## Troubleshooting

### Lỗi: `ImportError: libtk8.6.so`
```bash
# Ubuntu/Debian
sudo apt-get install python3-tk

# Fedora
sudo dnf install python3-tkinter
```

### Lỗi: Không hiển thị được cửa sổ
Kiểm tra biến môi trường DISPLAY (trên Linux):
```bash
echo $DISPLAY
# Nếu rỗng, cần cấu hình X11 forwarding
```

## Đóng góp

Mọi đóng góp về tính năng, ngôn ngữ mới, hoặc bug report đều được chào đón!

## License

MIT License - Xem file LICENSE trong repository gốc.

---

**Project Nayuki's QR Code Generator Library**
https://www.nayuki.io/page/qr-code-generator-library
Binary file added python/__pycache__/qrcodegen.cpython-312.pyc
Binary file not shown.
98 changes: 84 additions & 14 deletions python/qrcodegen-demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,25 +171,95 @@ def do_mask_demo() -> None:

# ---- Utilities ----

def to_svg_str(qr: QrCode, border: int) -> str:
"""Returns a string of SVG code for an image depicting the given QR Code, with the given number
of border modules. The string always uses Unix newlines (\n), regardless of the platform."""
if border < 0:
raise ValueError("Border must be non-negative")
parts: list[str] = []
for y in range(qr.get_size()):
for x in range(qr.get_size()):
if qr.get_module(x, y):
parts.append(f"M{x+border},{y+border}h1v1h-1z")
return f"""<?xml version="1.0" encoding="UTF-8"?>
def to_svg_str(
qr: QrCode,
border: int = 4,
*,
scale: int = 1,
foreground_color: str = "#000000",
background_color: str = "#FFFFFF",
) -> str:
"""Returns a string of SVG code for an image depicting the given QR Code.

Args:
qr: The QR Code object to convert to SVG.
border: Number of border modules around the QR Code (default: 4).
scale: Size of each module in pixels (default: 1).
foreground_color: Color of the QR Code modules (default: "#000000").
background_color: Color of the background (default: "#FFFFFF").

Returns:
A string containing the complete SVG document.

Raises:
ValueError: If border is negative or scale is less than 1.

Example:
>>> qr = QrCode.encode_text("Hello, world!", QrCode.Ecc.LOW)
>>> svg = to_svg_str(qr, border=4, scale=10, foreground_color="#000080")
>>> print(svg)
"""
if border < 0:
raise ValueError(f"Border must be non-negative, got {border}")
if scale < 1:
raise ValueError(f"Scale must be at least 1, got {scale}")

size = qr.get_size()
scaled_size = size * scale
total_size = scaled_size + border * 2 * scale

parts: list[str] = []
for y in range(size):
for x in range(size):
if qr.get_module(x, y):
pos_x = (x * scale) + border * scale
pos_y = (y * scale) + border * scale
parts.append(f"M{pos_x},{pos_y}h{scale}v{scale}h{-scale}z")

return f"""<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 {qr.get_size()+border*2} {qr.get_size()+border*2}" stroke="none">
<rect width="100%" height="100%" fill="#FFFFFF"/>
<path d="{" ".join(parts)}" fill="#000000"/>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 {total_size} {total_size}" stroke="none">
\t<rect width="100%" height="100%" fill="{background_color}"/>
\t<path d="{" ".join(parts)}" fill="{foreground_color}"/>
</svg>
"""


def to_svg_file(
qr: QrCode,
filepath: str,
border: int = 4,
*,
scale: int = 1,
foreground_color: str = "#000000",
background_color: str = "#FFFFFF",
) -> None:
"""Writes the QR Code as an SVG file to the specified path.

Args:
qr: The QR Code object to convert to SVG.
filepath: Path where the SVG file will be saved.
border: Number of border modules around the QR Code (default: 4).
scale: Size of each module in pixels (default: 1).
foreground_color: Color of the QR Code modules (default: "#000000").
background_color: Color of the background (default: "#FFFFFF").

Example:
>>> qr = QrCode.encode_text("https://example.com", QrCode.Ecc.MEDIUM)
>>> to_svg_file(qr, "qrcode.svg", border=4, scale=10)
"""
svg_content = to_svg_str(
qr,
border=border,
scale=scale,
foreground_color=foreground_color,
background_color=background_color,
)
with open(filepath, "w", encoding="utf-8", newline="\n") as f:
f.write(svg_content)



def print_qr(qrcode: QrCode) -> None:
"""Prints the given QrCode object to the console."""
border = 4
Expand Down
Loading