[Qt扒手2] PyQt5 路径绘画例子

【说明】

此例扒自 Qt 官网,原例是 C++ 代码,我把它改写成了 Python + PyQt5 版本。

有了前一个例子的成功,这个例子改写的非常之快。记得第一个例子花了我几天的时间,而这个例子只花了半个小时。

当然,过程中也遇到了一些新问题,比如 renderAreas 被定义成 QList类,而QList类的迭代,调试了几次都报错。没有办法,干脆把renderAreas 修改定义为Python的 list 类型,然后就OK了!!

本例基于: Win7 + Python 3.4 + PyQt5

【效果图】

[Qt扒手2] PyQt5 路径绘画例子

对比原C++界面:

[Qt扒手2] PyQt5 路径绘画例子

【源代码】

 # 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_())
上一篇:第三周作业3——Bug Report


下一篇:爬虫凶猛:爬支付宝、爬微信、窃取数据/编程实战(2):爬虫架构