绘制太极图 - 使用 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()
相关推荐
心软且酷丶1 小时前
leetcode:2160. 拆分数位后四位数字的最小和(python3解法,数学相关算法题)
python·算法·leetcode
盛夏绽放3 小时前
Python常用高阶函数全面解析:通俗易懂的指南
前端·windows·python
仟濹4 小时前
Python - 文件部分
python
一点.点4 小时前
李沐动手深度学习(pycharm中运行笔记)——10.多层感知机+从零实现+简介实现
人工智能·笔记·python·深度学习·pycharm
那雨倾城4 小时前
使用 OpenCV 实现哈哈镜效果
人工智能·python·opencv·计算机视觉
蹦蹦跳跳真可爱5895 小时前
Python----循环神经网络(LSTM:长短期记忆网络)
人工智能·python·rnn·深度学习·神经网络·lstm
大模型铲屎官5 小时前
【深度学习-Day 16】梯度下降法 - 如何让模型自动变聪明?
开发语言·人工智能·pytorch·python·深度学习·llm·梯度下降
ZWaruler5 小时前
十三: 神经网络的学习
人工智能·python·神经网络·机器学习·损失函数
moxiaoran57536 小时前
Python学习笔记--Django 表单处理
笔记·python·学习
zhangfeng11336 小时前
Python 和 matplotlib 保存图像时,确保图像的分辨率和像素符合特定要求(如 64x64),批量保存 不溢出内存
开发语言·python·matplotlib