绘制太极图 - 使用 PyQt

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

PyQt:是什么鬼?

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

代码的开胃菜

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

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

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

绘制鱼形,添阴阳

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

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 操作,巧妙地画出了太极图的左半部分——黑鱼的形状。

白色大圆圈和小鱼眼

# 绘制白色大圆圈
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))

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

完整代码

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()

绘制太极图 - 使用 PyQt_第1张图片

增加旋转功能

绘制太极图 - 使用 PyQt_第2张图片

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()

你可能感兴趣的:(Python,GUI,python,pyqt)