绘制太极图 - 使用 PyQt

大家好!今天我们将一起来探讨一下如何使用PyQt,这是一个强大的Python库,来绘制一个传统的太极图。这个图案代表着古老的阴阳哲学,而我们的代码将以大白话的方式向你揭示它的奥秘。

PyQt:是什么鬼?

首先,我们得了解一下PyQt。它是一个Python库,让你能够创建漂亮、跨平台的桌面应用程序。要记住的一点是,它基于Qt,这是一个功能强大的图形用户界面框架。

代码的开胃菜

好的,现在让我们来看看代码的一些小细节。

python 复制代码
class TaiChiWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(100, 100, 200, 200)
        self.setWindowTitle('Tai Chi with Bezier Curve')

这里我们定义了一个名为 TaiChiWidget 的类,继承自 QWidget。在这个类的构造函数中,我们设置了窗口的大小和标题。

绘制鱼形,添阴阳

接下来的绘图操作是代码的精华。

python 复制代码
def paintEvent(self, event):
    painter = QPainter(self)
    painter.rotate(30)
    painter.setRenderHint(QPainter.Antialiasing)
    path = QPainterPath()
    # 绘制 左侧黑鱼
    c = QPointF(50, 50)
    rect = QRectF(0, 0, 100, 100)
    path.moveTo(c)
    path.arcTo(rect, 90.0, 180.0)
    path.arcTo(QRectF(25, 50, 50, 50), -90, 180.0)
    path.arcTo(QRectF(25, 0, 50, 50), -90, -180.0)

这段代码通过创建一个 QPainter 对象,实现了旋转、抗锯齿等效果。然后,通过 QPainterPath 对象,使用一系列的 arcTo 操作,巧妙地画出了太极图的左半部分------黑鱼的形状。

白色大圆圈和小鱼眼

python 复制代码
# 绘制白色大圆圈
painter.setBrush(Qt.white)
painter.setPen(Qt.white)
painter.drawEllipse(QPointF(50, 50), 50, 50)
painter.fillPath(path, QBrush(Qt.black))

# 绘制两个小圆圈(鱼眼)
painter.setPen(Qt.white)
painter.drawEllipse(QPointF(50, 75), 7, 7)
painter.setBrush(Qt.black)
painter.setPen(Qt.black)
painter.drawEllipse(QPointF(50, 25), 7, 7)
painter.setPen(QPen(Qt.black, 2))

这部分代码用于绘制太极图的右半部分,即白色的大圆圈和两个小黑白鱼眼。通过设置画刷和画笔的颜色,巧妙地营造出阴阳的对比。

完整代码

python 复制代码
import sys
from PyQt5.QtGui import QPainter, QPainterPath, QBrush, QPen, QColor, QTransform
from PyQt5.QtCore import Qt, QPointF, QRectF
from rotate_widget import RotatedWidget
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsProxyWidget, QPushButton, QLabel, \
    QVBoxLayout, QWidget
from PyQt5.QtCore import Qt


class TaiChiWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(100, 100, 200, 200)
        self.setWindowTitle('Tai Chi with Bezier Curve')

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        path = QPainterPath()
        # 绘制 左侧黑鱼
        c = QPointF(50, 50)
        rect = QRectF(0, 0, 100, 100)
        path.moveTo(c)
        path.arcTo(rect, 90.0, 180.0)
        path.arcTo(QRectF(25, 50, 50, 50), -90, 180.0)
        path.arcTo(QRectF(25, 0, 50, 50), -90, -180.0)

        # 绘制白色大圆圈
        painter.setBrush(Qt.white)
        painter.setPen(Qt.white)
        painter.drawEllipse(QPointF(50, 50), 50, 50)
        painter.fillPath(path, QBrush(Qt.black))

        # 绘制两个小圆圈(鱼眼)
        painter.setPen(Qt.white)
        painter.drawEllipse(QPointF(50, 75), 7, 7)
        painter.setBrush(Qt.black)
        painter.setPen(Qt.black)
        painter.drawEllipse(QPointF(50, 25), 7, 7)
        painter.setPen(QPen(Qt.black, 2))


def test():
    app = QApplication(sys.argv)
    tai_chi_widget = TaiChiWidget()
    tai_chi_widget.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    test()

增加旋转功能

python 复制代码
import sys
from PyQt5.QtGui import QPainter, QPainterPath, QBrush, QPen, QColor, QTransform
from PyQt5.QtCore import Qt, QPointF, QRectF
from rotate_widget import RotatedWidget
from PyQt5.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsProxyWidget, QPushButton, QLabel, \
    QVBoxLayout, QWidget
from PyQt5.QtCore import Qt


class RotatedWidget(QGraphicsView):
    def __init__(self, content_widget, angle, parent=None):
        super().__init__(parent)
        self.angle = angle
        scene = QGraphicsScene(self)
        self.setScene(scene)

        # 创建 QGraphicsProxyWidget
        self.proxy_widget = QGraphicsProxyWidget()
        self.proxy_widget.setWidget(content_widget)
        self.proxy_widget.setTransformOriginPoint(content_widget.width() / 2, content_widget.height() / 2)
        scene.addItem(self.proxy_widget)
        self.rotate(self.angle)
        self.startTimer(1000/60)

    def timerEvent(self, a0):
        self.angle -= 1
        self.rotate(self.angle)
        self.update()

    def rotate(self, angle):
        self.proxy_widget.setRotation(angle)


class TaiChiWidget2(QWidget):
    def __init__(self):
        super().__init__()
        self.radius = 100
        self.setGeometry(100, 100, 200, 200)
        self.setStyleSheet("background-color: white;")
        self.setWindowTitle('Tai Chi with Bezier Curve')

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(QPen(Qt.black, 0.5))

        path = QPainterPath()
        # 绘制 左侧黑鱼
        c = QPointF(self.radius, self.radius)
        rect = QRectF(0, 0, self.radius * 2, self.radius * 2)
        path.moveTo(c)
        path.arcTo(rect, 90.0, 180.0)
        path.arcTo(QRectF(self.radius / 2, self.radius, self.radius, self.radius), -90, 180.0)
        path.arcTo(QRectF(self.radius / 2, 0, self.radius, self.radius), -90, -180.0)

        # 绘制白色大圆圈
        painter.setBrush(Qt.white)
        painter.drawEllipse(QPointF(self.radius, self.radius), self.radius, self.radius)
        painter.fillPath(path, QBrush(Qt.black))

        # 绘制两个小圆圈(鱼眼)
        painter.setPen(Qt.white)
        painter.drawEllipse(QPointF(self.radius, self.radius * 3 / 2), self.radius * 0.15, self.radius * 0.15)
        painter.setBrush(Qt.black)
        painter.setPen(Qt.black)
        painter.drawEllipse(QPointF(self.radius, self.radius / 2), self.radius * 0.15, self.radius * 0.15)


def test():
    app = QApplication(sys.argv)
    tai_chi_widget = TaiChiWidget2()
    t = RotatedWidget(tai_chi_widget, 60)
    t.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    test()
相关推荐
玩大数据的龙威7 小时前
农经权二轮延包—各种地块示意图
python·arcgis
ZH15455891318 小时前
Flutter for OpenHarmony Python学习助手实战:数据库操作与管理的实现
python·学习·flutter
belldeep8 小时前
python:用 Flask 3 , mistune 2 和 mermaid.min.js 10.9 来实现 Markdown 中 mermaid 图表的渲染
javascript·python·flask
喵手8 小时前
Python爬虫实战:电商价格监控系统 - 从定时任务到历史趋势分析的完整实战(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·电商价格监控系统·从定时任务到历史趋势分析·采集结果sqlite存储
喵手8 小时前
Python爬虫实战:京东/淘宝搜索多页爬虫实战 - 从反爬对抗到数据入库的完整工程化方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·京东淘宝页面数据采集·反爬对抗到数据入库·采集结果csv导出
B站_计算机毕业设计之家8 小时前
猫眼电影数据可视化与智能分析平台 | Python Flask框架 Echarts 推荐算法 爬虫 大数据 毕业设计源码
python·机器学习·信息可视化·flask·毕业设计·echarts·推荐算法
PPPPPaPeR.8 小时前
光学算法实战:深度解析镜片厚度对前后表面折射/反射的影响(纯Python实现)
开发语言·python·数码相机·算法
JaydenAI8 小时前
[拆解LangChain执行引擎] ManagedValue——一种特殊的只读虚拟通道
python·langchain
骇城迷影8 小时前
Makemore 核心面试题大汇总
人工智能·pytorch·python·深度学习·线性回归
长安牧笛8 小时前
反传统学习APP,摒弃固定课程顺序,根据用户做题正确性,学习速度,动态调整课程难度,比如某知识点学不会,自动推荐基础讲解和练习题,学习后再进阶,不搞一刀切。
python·编程语言