大家好!今天我们将一起来探讨一下如何使用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 Qtclass 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()
增加旋转功能
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 Qtclass RotatedWidget(QGraphicsView):def __init__(self, content_widget, angle, parent=None):super().__init__(parent)self.angle = anglescene = QGraphicsScene(self)self.setScene(scene)# 创建 QGraphicsProxyWidgetself.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 -= 1self.rotate(self.angle)self.update()def rotate(self, angle):self.proxy_widget.setRotation(angle)class TaiChiWidget2(QWidget):def __init__(self):super().__init__()self.radius = 100self.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()