http://www.cnblogs.com/hhh5460/p/4281587.html
# File: Painter Paths Example.py # Author: Robin # Date: 2015.2.9 # C++: http://doc.qt.io/qt-5/qtwidgets-painting-painterpaths-example.html import math from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class RenderArea(QWidget): def __init__(self, path, parent=None): super(RenderArea, self).__init__(parent) self.penWidth = 1 self.rotationAngle = 0 self.path = path self.setBackgroundRole(QPalette.Base) self.setAutoFillBackground(True) def minimumSizeHint(self): return QSize(50, 50) def sizeHint(self): return QSize(100, 100) def setFillRule(self, rule): self.path.setFillRule(rule) self.update() def setFillGradient(self, color1, color2): self.fillColor1 = color1 self.fillColor2 = color2 self.update() def setPenWidth(self, width): self.penWidth = width self.update() def setPenColor(self, color): self.penColor = color self.update() def setRotationAngle(self, degrees): self.rotationAngle = degrees self.update() def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.scale(self.width() / 100.0, self.height() / 100.0) painter.translate(50.0, 50.0) painter.rotate(-self.rotationAngle) painter.translate(-50.0, -50.0) painter.setPen(QPen(self.penColor, self.penWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) gradient = QLinearGradient(0, 0, 0, 100) gradient.setColorAt(0.0, self.fillColor1) gradient.setColorAt(1.0, self.fillColor2) painter.setBrush(gradient) painter.drawPath(self.path) class MyWindow(QWidget): def __init__(self): super(MyWindow, self).__init__() # self.setUi() # self.Pi = 3.1415926 # 矩形路径 self.rectPath = QPainterPath() self.rectPath.moveTo(20.0, 30.0) self.rectPath.lineTo(80.0, 30.0) self.rectPath.lineTo(80.0, 70.0) self.rectPath.lineTo(20.0, 70.0) self.rectPath.closeSubpath() # 圆角矩形路径 self.roundRectPath = QPainterPath() self.roundRectPath.moveTo(80.0, 35.0) self.roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0) self.roundRectPath.lineTo(25.0, 30.0) self.roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0) self.roundRectPath.lineTo(20.0, 65.0) self.roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0) self.roundRectPath.lineTo(75.0, 70.0) self.roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0) self.roundRectPath.closeSubpath() # 椭圆路径 self.ellipsePath = QPainterPath() self.ellipsePath.moveTo(80.0, 50.0) self.ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0) # 饼图路径 self.piePath = QPainterPath() self.piePath.moveTo(50.0, 50.0) self.piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0) self.piePath.closeSubpath() # 多边形路径 self.polygonPath = QPainterPath() self.polygonPath.moveTo(10.0, 80.0) self.polygonPath.lineTo(20.0, 10.0) self.polygonPath.lineTo(80.0, 30.0) self.polygonPath.lineTo(90.0, 70.0) self.polygonPath.closeSubpath() # 组合路径 self.groupPath = QPainterPath() self.groupPath.moveTo(60.0, 40.0) self.groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0) self.groupPath.moveTo(40.0, 40.0) self.groupPath.lineTo(40.0, 80.0) self.groupPath.lineTo(80.0, 80.0) self.groupPath.lineTo(80.0, 40.0) self.groupPath.closeSubpath() # 文字路径 self.textPath = QPainterPath() self.timesFont = QFont("Times", 50) self.timesFont.setStyleStrategy(QFont.ForceOutline) self.textPath.addText(10, 70, self.timesFont, "Qt") # 贝兹尔路径 self.bezierPath = QPainterPath() self.bezierPath.moveTo(20, 30) self.bezierPath.cubicTo(80, 0, 50, 50, 80, 80) self.starPath = QPainterPath() self.starPath.moveTo(90, 50) for i in range(5): self.starPath.lineTo(50 + 40 * math.cos(0.8 * i * math.pi), 50 + 40 * math.sin(0.8 * i * math.pi)) self.starPath.closeSubpath() self.renderAreas = [] self.renderAreas.append(RenderArea(self.rectPath)) self.renderAreas.append(RenderArea(self.roundRectPath)) self.renderAreas.append(RenderArea(self.ellipsePath)) self.renderAreas.append(RenderArea(self.piePath)) self.renderAreas.append(RenderArea(self.polygonPath)) self.renderAreas.append(RenderArea(self.groupPath)) self.renderAreas.append(RenderArea(self.textPath)) self.renderAreas.append(RenderArea(self.bezierPath)) self.renderAreas.append(RenderArea(self.starPath)) # def setUi(self): self.fillRuleComboBox = QComboBox() self.fillRuleComboBox.addItem("Odd Even", Qt.OddEvenFill) self.fillRuleComboBox.addItem("Winding", Qt.WindingFill) self.fillRuleLabel = QLabel("Fill &Rule:") self.fillRuleLabel.setBuddy(self.fillRuleComboBox) self.fillColor1ComboBox = QComboBox() self.populateWithColors(self.fillColor1ComboBox) self.fillColor1ComboBox.setCurrentIndex(self.fillColor1ComboBox.findText("mediumslateblue")) self.fillColor2ComboBox = QComboBox() self.populateWithColors(self.fillColor2ComboBox) self.fillColor2ComboBox.setCurrentIndex(self.fillColor2ComboBox.findText("cornsilk")) self.fillGradientLabel = QLabel("&Fill Gradient:") self.fillGradientLabel.setBuddy(self.fillColor1ComboBox) self.fillToLabel = QLabel("to") self.fillToLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.penWidthSpinBox = QSpinBox() self.penWidthSpinBox.setRange(0, 20) self.penWidthLabel = QLabel("&Pen Width:") self.penWidthLabel.setBuddy(self.penWidthSpinBox) self.penColorComboBox = QComboBox() self.populateWithColors(self.penColorComboBox) self.penColorComboBox.setCurrentIndex(self.penColorComboBox.findText("darkslateblue")) self.penColorLabel = QLabel("Pen &Color:") self.penColorLabel.setBuddy(self.penColorComboBox) self.rotationAngleSpinBox = QSpinBox() self.rotationAngleSpinBox.setRange(0, 359) self.rotationAngleSpinBox.setWrapping(True) self.rotationAngleSpinBox.setSuffix("°") self.rotationAngleLabel = QLabel("&Rotation Angle:") self.rotationAngleLabel.setBuddy(self.rotationAngleSpinBox) self.fillRuleComboBox.activated.connect(self.fillRuleChanged) self.fillColor1ComboBox.activated.connect(self.fillGradientChanged) self.fillColor2ComboBox.activated.connect(self.fillGradientChanged) self.penColorComboBox.activated.connect(self.penColorChanged) for it in self.renderAreas: self.penWidthSpinBox.valueChanged.connect(it.setPenWidth) self.rotationAngleSpinBox.valueChanged.connect(it.setRotationAngle) topLayout = QGridLayout() i = 0 for i, it in enumerate(self.renderAreas): topLayout.addWidget(it, i // 3, i % 3) mainLayout = QGridLayout() mainLayout.addLayout(topLayout, 0, 0, 1, 4) mainLayout.addWidget(self.fillRuleLabel, 1, 0) mainLayout.addWidget(self.fillRuleComboBox, 1, 1, 1, 3) mainLayout.addWidget(self.fillGradientLabel, 2, 0) mainLayout.addWidget(self.fillColor1ComboBox, 2, 1) mainLayout.addWidget(self.fillToLabel, 2, 2) mainLayout.addWidget(self.fillColor2ComboBox, 2, 3) mainLayout.addWidget(self.penWidthLabel, 3, 0) mainLayout.addWidget(self.penWidthSpinBox, 3, 1, 1, 3) mainLayout.addWidget(self.penColorLabel, 4, 0) mainLayout.addWidget(self.penColorComboBox, 4, 1, 1, 3) mainLayout.addWidget(self.rotationAngleLabel, 5, 0) mainLayout.addWidget(self.rotationAngleSpinBox, 5, 1, 1, 3) self.setLayout(mainLayout) self.fillRuleChanged() self.fillGradientChanged() self.penColorChanged() self.penWidthSpinBox.setValue(2) self.setWindowTitle("Painter Paths") def fillRuleChanged(self): rule = self.currentItemData(self.fillRuleComboBox) for it in self.renderAreas: it.setFillRule(rule) def fillGradientChanged(self): color1 = self.currentItemData(self.fillColor1ComboBox) color2 = self.currentItemData(self.fillColor2ComboBox) for it in self.renderAreas: it.setFillGradient(color1, color2) def penColorChanged(self): color = self.currentItemData(self.penColorComboBox) for it in self.renderAreas: it.setPenColor(color) @staticmethod def populateWithColors(comboBox): colorNames = QColor.colorNames() for name in colorNames: comboBox.addItem(name, QColor(name)) @staticmethod def currentItemData(comboBox): return comboBox.itemData(comboBox.currentIndex(), Qt.UserRole) if __name__ == "__main__": import sys app = QApplication(sys.argv) win = MyWindow() win.show() sys.exit(app.exec_())