【说明】

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

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

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

本例基于: Win7 + Python 3.4 + PyQt5

【效果图】

对比原C++界面:

【源代码】

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

[Qt扒手2] PyQt5 路径绘画例子的更多相关文章

  1. [Qt扒手] PyQt5 基础绘画例子

    [说明] 好吧,坦白从宽,我是Qt扒手(不要鄙视我).这是我根据qt官网提供的C++版本的例子(http://doc.qt.io/qt-5/qtwidgets-painting-basicdrawin ...

  2. 基于Qt Designer和PyQt5的桌面软件开发--环境搭建和入门例子

      本文介绍了如何使用技术栈PyCharm+Qt Designer+PyQt5来开发桌面软件,从环境搭建.例子演示到对容易混淆概念的解释.文中用到的全部软件+代码下载链接为:https://url39 ...

  3. qmake.exe是在Qt安装编译时生成的,里面内嵌了Qt相关的一些路径(最简单的方法是保持一样的安装路径,最方便的办法是设置qt.conf文件)

    在网上直接下载别人编译好的Qt库,为自己使用省了不少事.但往往也会遇到些问题,其中Qt version is not properly installed,please run make instal ...

  4. QT应用程序 安装路径中文异常问题

    [1]QT 安装中文路径启动异常问题 最近在搞一个很简单的QT应用程序,开发环境VS2017 + QT5.9,线上异常报错:安装中文路径下启动崩溃~~~~ 最后,本地调试Debug版本,发现安装中文路 ...

  5. Qt内的各种路径(让人迷惑)

    Qt里面各种获取程序路径或者当前路径的写法,在此梳理一下,以防今后开发的程序中路径不统一 1.利用QDir获取路径 QDir::currentPath() 此路径是项目编译生成的路径即可执行文件所在目 ...

  6. 【QT】利用pyqt5实现简单界面

    Topic: 利用pyqt5编写简单界面Env:win10 + Pycharm2018 + Python 3.6.8Date: 2019/4/29 by hw_Chen2018            ...

  7. qt 3 获取文件路径中的一部分

    QList<QString> qlist = path.split(QRegExp("[\\\\/]")); QString FileName = qlist.at(q ...

  8. Qt Style Sheets Examples(官方例子目录,很全)

    Contents Style Sheet Usage Customizing the Foreground and Background Colors Customizing Using Dynami ...

  9. QT实现拖放文件(有例子,并且图文并茂,非常清楚)

    转自:http://my.oschina.net/voler/blog/345722 目录[-] 0. 源代码下载地址 1. 简单文件拖放 2. 复杂文件拖放 3. 通过按钮来完成列表数据的转移 4. ...

随机推荐

  1. Oracle EBS 新增OAFM个数

    在 $INST_TOP/ora/10.1.3/opmn/conf/opmn.xml中找到<process-type id="oafm" module-id="OC4 ...

  2. [翻译] PJR Signature View

    PJR Signature View https://github.com/paritsohraval100/PJRSignatureDemo It is a UIView subclass by w ...

  3. 转载:从程序员的角度看ASCII, GB2312, UNICODE, UTF-8

    以下内容转自博客:http://blog.chinaunix.net/uid-22670933-id-1771613.html. 一.字符编码是怎么回事 0. 概念 字节是计算机的最基本存储单位,一个 ...

  4. 【Excel】如何用SUMIF实现SUMIFS的功能

    如何用SUMIF实现SUMIFS的功能   添加辅助列,辅助列内容为"条件区域1内容+条件区域内容2" 举个例子,我要挑选出"二车间"的"过桥过路费& ...

  5. Python成员运算符

    Python成员运算符 其他语言没有,是否包含运算符,主要应用在字符串或者集合中 测试实例中包含了一系列的成员,包括字符串,列表或元组. #使用场景01:字符串是否包含另外一个字符串? str01 = ...

  6. ZT 类模板Stack的实现 by vector

    *//*第3章 类模板 与函数相似,类也可以被一种或多种类型参数化.容器类就是一个具有这种特性的典型例子,它通常被用于管理某种特定类型的元素.只要使用类模板,你就可以实现容器类,而不需要确定容器中元素 ...

  7. 使用concurrent.futures模块并发,实现进程池、线程池

    Python标准库为我们提供了threading和multiprocessing模块编写相应的异步多线程/多进程代码 从Python3.2开始,标准库为我们提供了concurrent.futures模 ...

  8. python中string格式化

    python中可以对string, int, float等数据类型进行格式化操作.下面举例来说明一些常用操作. 先贴出 python 对 String Formatting Operations 讲解 ...

  9. 学习python第三天之多行函数

    多行函数:(聚合函数/分组函数) 解释:多条数据进入,单条结果出来(多进单出) 1).max(obj):最大值 2).min(obj):最小值 3).sum(num):求和 4).avg(num):求 ...

  10. OC中实现可变参数

    通过哨兵参数实现,相当于nil. 1.c语言中 #import <stdio.h> #import <stdarg.h> int addemUp(int firstNum,.. ...