绘制太极图 - 使用 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()
相关推荐
databook5 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar6 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780517 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_7 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机13 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机14 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机14 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机14 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i15 小时前
drf初步梳理
python·django
每日AI新事件15 小时前
python的异步函数
python