🧱 使用 PySide6 构建 QRForge PRO(适合初学者的指南)
It looks like only the source citation was provided, and there’s no additional text to translate. Could you please share the rest of the content you’d like translated? Once you do, I’ll keep the source line unchanged and translate the rest into Simplified Chinese while preserving all formatting, code blocks, URLs, and technical terms.
0️⃣ 你将构建的内容
在本教程结束时,你将拥有一个功能完整的 Qt 应用程序,能够像平面设计师一样设计二维码。
1️⃣ 项目设置
安装依赖
pip install PySide6 qrcode pillow requests
文件结构
qrforge/
├─ main.py
├─ logo.ico
2️⃣ 导入所需内容
# Standard library
import sys, os, math, requests
# QR helpers
import qrcode
from PIL import Image
# Qt imports
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
from PySide6.QtSvg import QSvgGenerator
from PySide6.QtGui import QPdfWriter, QPageSize
这些导入为我们提供了:
- 窗口和对话框 – 通过
QtWidgets - 矢量绘图 – 通过
QtGui与QtSvg - 基于场景的渲染 – 通过
QGraphicsScene/View - SVG/PDF 导出 – 通过
QSvgGenerator与QPdfWriter
3️⃣ 应用元数据
集中管理元数据可以保持代码简洁且可复用。
APP_NAME = "QRForge PRO"
APP_VERSION = "2.0.0"
APP_AUTHOR = "Mate Technologies"
APP_URL = "https://matetools.gumroad.com"
4️⃣ 实用函数
# Resource loader (for PyInstaller compatibility)
def resource_path(name):
base = getattr(sys, "_MEIPASS", os.path.dirname(__file__))
return os.path.join(base, name)
# URL shortener (TinyURL API)
def shorten_url(url):
try:
r = requests.get(
f"https://tinyurl.com/api-create.php?url={url}",
timeout=5,
)
return r.text if r.status_code == 200 else url
except Exception:
return url
# Wi‑Fi QR payload format
def wifi_payload(ssid, pwd, enc):
# enc can be "WPA", "WEP", or "NONE"
return f"WIFI:S:{ssid};T:{enc if enc!='NONE' else ''};P:{pwd};;"
5️⃣ 创建 QR 码 Graphics 项目
与其直接渲染图像,我们创建一个自定义 QGraphicsItem。
这样我们就拥有 拖拽、旋转 和 选中轮廓。
QRItem 类骨架
class QRItem(QGraphicsItem):
def __init__(self, data):
super().__init__()
self.data = data
self.size = 300 # default pixel size
self.rotation_angle = 0
self.fill = QColor("black") # QR fill colour
self.bg = QColor("white") # background colour
self.transparent = False
self.generate()
生成 QR 图像
def generate(self):
qr = qrcode.QRCode(border=1)
qr.add_data(self.data)
qr.make(fit=True)
back = None if self.transparent else self.bg.name()
img = qr.make_image(
fill_color=self.fill.name(),
back_color=back,
).convert("RGBA")
# Convert PIL → QImage
self.qimage = QImage(
img.tobytes("raw", "RGBA"),
img.width,
img.height,
QImage.Format_RGBA8888,
)
绘制与选中轮廓
def paint(self, painter, *_):
painter.save()
painter.rotate(self.rotation_angle)
painter.drawImage(self.boundingRect(), self.qimage)
painter.restore()
if self.isSelected():
painter.setPen(QPen(QColor("#00E676"), 2, Qt.DashLine))
painter.drawRect(self.boundingRect())
6️⃣ Canvas: 缩放、拖动、旋转
我们扩展 QGraphicsView 来处理鼠标滚轮缩放和 ALT + 鼠标 旋转。
class Canvas(QGraphicsView):
def __init__(self, scene, parent=None):
super().__init__(scene, parent)
self.setRenderHint(QPainter.Antialiasing)
self.rotating = False
# ---------- Zoom ----------
def wheelEvent(self, event):
factor = 1.15 if event.angleDelta().y() > 0 else 0.85
self.scale(factor, factor)
# ---------- Rotation ----------
def mousePressEvent(self, event):
if event.modifiers() & Qt.AltModifier and event.button() == Qt.LeftButton:
self.rotating = True
super().mousePressEvent(event)
def mouseReleaseEvent(self, event):
self.rotating = False
super().mouseReleaseEvent(event)
def mouseMoveEvent(self, event):
if self.rotating:
item = self.itemAt(event.position().toPoint())
if isinstance(item, QRItem):
dx = event.scenePosition().x() - item.scenePos().x()
dy = event.scenePosition().y() - item.scenePos().y()
item.rotation_angle = math.degrees(math.atan2(dy, dx))
item.update()
else:
super().mouseMoveEvent(event)
7️⃣ 主窗口 (QMainWindow)
所有 UI 组件在此组装。
class QRForgeStudio(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle(f"{APP_NAME} v{APP_VERSION}")
# Scene & canvas
self.scene = QGraphicsScene(-5000, -5000, 10000, 10000)
self.canvas = Canvas(self.scene)
self.setCentralWidget(self.canvas)
# UI – left dock
self._setup_left_dock()
8️⃣ 左侧控制面板 (DockWidget)
模式选择器
self.mode = QComboBox()
self.mode.addItems(["Text", "URL", "Wi‑Fi"])
内容输入
self.text = QTextEdit()
self.text.setPlaceholderText("Enter content…")
颜色与背景控制
self.fill_btn = QPushButton("🎨 Fill Colour")
self.bg_btn = QPushButton("🖌 Background")
self.trans = QCheckBox("Transparent Background")
(附加的 Wi‑Fi 字段 – self.ssid、self.pwd、self.enc – 在同一停靠窗口中创建。)
9️⃣ 将 QR 添加到画布
def add_qr(self):
mode = self.mode.currentText()
if mode == "Text":
data = self.text.toPlainText()
elif mode == "URL":
data = shorten_url(self.text.toPlainText())
else: # Wi‑Fi
data = wifi_payload(
self.ssid.text(),
self.pwd.text(),
self.enc.currentText(),
)
item = QRItem(data)
self.scene.addItem(item)
item.setPos(0, 0) # centre of the canvas
🔟 导出 (PNG, SVG, PDF)
PNG 导出(光栅)
def export_png(self, path, width=2000, height=2000):
img = QImage(width, height, QImage.Format_ARGB32)
img.fill(Qt.transparent)
painter = QPainter(img)
self.scene.render(painter)
painter.end()
img.save(path)
SVG 导出(矢量)
def export_svg(self, path, rect=None):
generator = QSvgGenerator()
generator.setFileName(path)
generator.setSize(QSize(2000, 2000))
generator.setViewBox(rect or self.scene.sceneRect())
generator.setTitle(APP_NAME)
generator.setDescription("QRForge PRO SVG export")
painter = QPainter(generator)
self.scene.render(painter)
painter.end()
PDF 导出(矢量)
def export_pdf(self, path, rect=None):
writer = QPdfWriter(path)
writer.setPageSize(QPageSize(QPageSize.A4))
writer.setResolution(300)
painter = QPainter(writer)
self.scene.render(painter, target=writer.pageRect(), source=rect or self.scene.sceneRect())
painter.end()
🎉 总结
您现在拥有一个使用 Python、PySide6 和 qrcode 构建的 完整、交互式 QR 码设计工作室。随意:
- 添加更多 效果(渐变、阴影)
- 使用
QUndoStack实现 撤销/重做 - 使用 PyInstaller 打包应用 (
pyinstaller --onefile main.py)
祝编码愉快! 🚀
QRForge PRO – 初学者友好的 PySide6 二维码工作室
PDF 导出(可直接打印)
pdf = QPdfWriter(path)
pdf.setPageSize(QPageSize.A4)
pdf.setResolution(300)
每个二维码占据单独的一页。
1️⃣ 入口点
if __name__ == "__main__":
app = QApplication(sys.argv)
win = QRForgeStudio()
win.show()
sys.exit(app.exec())
🎉 最终结果
你现在拥有:
- 设计师友好的 QR 工作室
- 矢量和打印导出
- 交互式画布控制
- 干净的 PySide6 架构
👉 完整仓库:
🚀 接下来要构建的内容
- 预设模板
- 徽标嵌入
- 批量二维码生成
- PyInstaller 打包
祝构建愉快! 🧡
关于本教程
我编写了一篇 Dev.to 风格、适合初学者、一步步引导的教程,从零开始完整演示 QRForge PRO 的开发过程。
这个版本的特别之处(特意如此)
- ✅ 将项目拆分为小而易懂的章节
- ✅ 使用简短的代码块,并在后面直接给出解释
- ✅ 说明每个 Qt/QR 概念 为何 存在,而不仅仅是 做什么
- ✅ 对刚接触 PySide6 + GraphicsView 的开发者保持友好
- ✅ 提供完整源码克隆链接,避免一次性展示大量难以阅读的代码
适用场景
- 在 Dev.to 上发布
- Medium / Hashnode 跨平台转载
- 开源项目文档
- 可视化教学 PySide6
