zoukankan      html  css  js  c++  java
  • [Qt扒手2] PyQt5 路径绘画例子

    【说明】

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

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

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

    本例基于: Win7 + Python 3.4 + PyQt5

    【效果图】

    对比原C++界面:

    【源代码】

      1 # File: Painter Paths Example.py
      2 # Author: Robin
      3 # Date: 2015.2.9
      4 # C++: http://doc.qt.io/qt-5/qtwidgets-painting-painterpaths-example.html
      5 
      6 import math
      7 from PyQt5.QtCore import *
      8 from PyQt5.QtGui import *
      9 from PyQt5.QtWidgets import *
     10 
     11 
     12 class RenderArea(QWidget):
     13     def __init__(self, path, parent=None):
     14         super(RenderArea, self).__init__(parent)
     15         self.penWidth = 1
     16         self.rotationAngle = 0
     17         self.path = path
     18         self.setBackgroundRole(QPalette.Base)
     19         self.setAutoFillBackground(True)
     20         
     21     def minimumSizeHint(self):
     22         return QSize(50, 50)
     23         
     24     def sizeHint(self):
     25         return QSize(100, 100)
     26         
     27     def setFillRule(self, rule):
     28         self.path.setFillRule(rule)
     29         self.update()
     30         
     31     def setFillGradient(self, color1, color2):
     32         self.fillColor1 = color1
     33         self.fillColor2 = color2
     34         self.update()
     35         
     36     def setPenWidth(self, width):
     37         self.penWidth = width
     38         self.update()
     39         
     40     def setPenColor(self, color):
     41         self.penColor = color
     42         self.update()
     43         
     44     def setRotationAngle(self, degrees):
     45         self.rotationAngle = degrees
     46         self.update()
     47         
     48     def paintEvent(self, event):
     49         painter = QPainter(self)
     50         painter.setRenderHint(QPainter.Antialiasing)
     51         painter.scale(self.width() / 100.0, self.height() / 100.0)
     52         painter.translate(50.0, 50.0)
     53         painter.rotate(-self.rotationAngle)
     54         painter.translate(-50.0, -50.0)
     55         painter.setPen(QPen(self.penColor, self.penWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
     56         gradient = QLinearGradient(0, 0, 0, 100)
     57         gradient.setColorAt(0.0, self.fillColor1)
     58         gradient.setColorAt(1.0, self.fillColor2)
     59         painter.setBrush(gradient)
     60         painter.drawPath(self.path)
     61 
     62 
     63 class MyWindow(QWidget):
     64     
     65     def __init__(self):
     66         super(MyWindow, self).__init__() 
     67         #self.setUi()
     68         #self.Pi = 3.1415926
     69         # 矩形路径
     70         self.rectPath = QPainterPath()
     71         self.rectPath.moveTo(20.0, 30.0)
     72         self.rectPath.lineTo(80.0, 30.0)
     73         self.rectPath.lineTo(80.0, 70.0)
     74         self.rectPath.lineTo(20.0, 70.0)
     75         self.rectPath.closeSubpath()
     76         # 圆角矩形路径
     77         self.roundRectPath = QPainterPath()
     78         self.roundRectPath.moveTo(80.0, 35.0)
     79         self.roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0)
     80         self.roundRectPath.lineTo(25.0, 30.0)
     81         self.roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0)
     82         self.roundRectPath.lineTo(20.0, 65.0)
     83         self.roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0)
     84         self.roundRectPath.lineTo(75.0, 70.0)
     85         self.roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0)
     86         self.roundRectPath.closeSubpath()
     87         # 椭圆路径
     88         self.ellipsePath = QPainterPath()
     89         self.ellipsePath.moveTo(80.0, 50.0)
     90         self.ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0)
     91         # 饼图路径
     92         self.piePath = QPainterPath()
     93         self.piePath.moveTo(50.0, 50.0)
     94         self.piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0)
     95         self.piePath.closeSubpath()
     96         # 多边形路径
     97         self.polygonPath = QPainterPath()
     98         self.polygonPath.moveTo(10.0, 80.0)
     99         self.polygonPath.lineTo(20.0, 10.0)
    100         self.polygonPath.lineTo(80.0, 30.0)
    101         self.polygonPath.lineTo(90.0, 70.0)
    102         self.polygonPath.closeSubpath()
    103         # 组合路径
    104         self.groupPath = QPainterPath()
    105         self.groupPath.moveTo(60.0, 40.0)
    106         self.groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0)
    107         self.groupPath.moveTo(40.0, 40.0)
    108         self.groupPath.lineTo(40.0, 80.0)
    109         self.groupPath.lineTo(80.0, 80.0)
    110         self.groupPath.lineTo(80.0, 40.0)
    111         self.groupPath.closeSubpath()
    112         # 文字路径
    113         self.textPath = QPainterPath()
    114         self.timesFont = QFont("Times", 50)
    115         self.timesFont.setStyleStrategy(QFont.ForceOutline)
    116         self.textPath.addText(10, 70, self.timesFont, "Qt")
    117         # 贝兹尔路径
    118         self.bezierPath = QPainterPath()
    119         self.bezierPath.moveTo(20, 30)
    120         self.bezierPath.cubicTo(80, 0, 50, 50, 80, 80)
    121         
    122         self.starPath = QPainterPath()
    123         self.starPath.moveTo(90, 50)
    124         for i in range(5):
    125             self.starPath.lineTo(50 + 40 * math.cos(0.8 * i * math.pi),
    126                             50 + 40 * math.sin(0.8 * i * math.pi))
    127         self.starPath.closeSubpath()
    128         
    129         self.renderAreas = []
    130         self.renderAreas.append(RenderArea(self.rectPath))
    131         self.renderAreas.append(RenderArea(self.roundRectPath))
    132         self.renderAreas.append(RenderArea(self.ellipsePath))
    133         self.renderAreas.append(RenderArea(self.piePath))
    134         self.renderAreas.append(RenderArea(self.polygonPath))
    135         self.renderAreas.append(RenderArea(self.groupPath))
    136         self.renderAreas.append(RenderArea(self.textPath))
    137         self.renderAreas.append(RenderArea(self.bezierPath))
    138         self.renderAreas.append(RenderArea(self.starPath))
    139         
    140     #def setUi(self):    
    141         self.fillRuleComboBox = QComboBox()
    142         self.fillRuleComboBox.addItem("Odd Even", Qt.OddEvenFill)
    143         self.fillRuleComboBox.addItem("Winding", Qt.WindingFill)
    144 
    145         self.fillRuleLabel = QLabel("Fill &Rule:")
    146         self.fillRuleLabel.setBuddy(self.fillRuleComboBox)
    147 
    148         self.fillColor1ComboBox = QComboBox()
    149         self.populateWithColors(self.fillColor1ComboBox)
    150         self.fillColor1ComboBox.setCurrentIndex(self.fillColor1ComboBox.findText("mediumslateblue"))
    151 
    152         self.fillColor2ComboBox = QComboBox()
    153         self.populateWithColors(self.fillColor2ComboBox)
    154         self.fillColor2ComboBox.setCurrentIndex(self.fillColor2ComboBox.findText("cornsilk"))
    155 
    156         self.fillGradientLabel = QLabel("&Fill Gradient:")
    157         self.fillGradientLabel.setBuddy(self.fillColor1ComboBox)
    158 
    159         self.fillToLabel = QLabel("to")
    160         self.fillToLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
    161 
    162         self.penWidthSpinBox = QSpinBox()
    163         self.penWidthSpinBox.setRange(0, 20)
    164 
    165         self.penWidthLabel = QLabel("&Pen Width:")
    166         self.penWidthLabel.setBuddy(self.penWidthSpinBox)
    167 
    168         self.penColorComboBox = QComboBox()
    169         self.populateWithColors(self.penColorComboBox)
    170         self.penColorComboBox.setCurrentIndex(self.penColorComboBox.findText("darkslateblue"))
    171 
    172         self.penColorLabel = QLabel("Pen &Color:")
    173         self.penColorLabel.setBuddy(self.penColorComboBox)
    174 
    175         self.rotationAngleSpinBox = QSpinBox()
    176         self.rotationAngleSpinBox.setRange(0, 359)
    177         self.rotationAngleSpinBox.setWrapping(True)
    178         self.rotationAngleSpinBox.setSuffix("°")
    179 
    180         self.rotationAngleLabel = QLabel("&Rotation Angle:")
    181         self.rotationAngleLabel.setBuddy(self.rotationAngleSpinBox)
    182 
    183         self.fillRuleComboBox.activated.connect(self.fillRuleChanged)
    184         self.fillColor1ComboBox.activated.connect(self.fillGradientChanged)
    185         self.fillColor2ComboBox.activated.connect(self.fillGradientChanged)
    186         self.penColorComboBox.activated.connect(self.penColorChanged)
    187 
    188         for it in self.renderAreas: 
    189             self.penWidthSpinBox.valueChanged.connect(it.setPenWidth)
    190             self.rotationAngleSpinBox.valueChanged.connect(it.setRotationAngle)
    191 
    192         
    193         topLayout = QGridLayout()
    194 
    195         i = 0
    196         for i, it in enumerate(self.renderAreas):
    197             topLayout.addWidget(it, i // 3, i % 3)
    198             
    199 
    200         mainLayout = QGridLayout()
    201         mainLayout.addLayout(topLayout, 0, 0, 1, 4)
    202         mainLayout.addWidget(self.fillRuleLabel, 1, 0)
    203         mainLayout.addWidget(self.fillRuleComboBox, 1, 1, 1, 3)
    204         mainLayout.addWidget(self.fillGradientLabel, 2, 0)
    205         mainLayout.addWidget(self.fillColor1ComboBox, 2, 1)
    206         mainLayout.addWidget(self.fillToLabel, 2, 2)
    207         mainLayout.addWidget(self.fillColor2ComboBox, 2, 3)
    208         mainLayout.addWidget(self.penWidthLabel, 3, 0)
    209         mainLayout.addWidget(self.penWidthSpinBox, 3, 1, 1, 3)
    210         mainLayout.addWidget(self.penColorLabel, 4, 0)
    211         mainLayout.addWidget(self.penColorComboBox, 4, 1, 1, 3)
    212         mainLayout.addWidget(self.rotationAngleLabel, 5, 0)
    213         mainLayout.addWidget(self.rotationAngleSpinBox, 5, 1, 1, 3)
    214         self.setLayout(mainLayout)
    215 
    216         self.fillRuleChanged()
    217         self.fillGradientChanged()
    218         self.penColorChanged()
    219         self.penWidthSpinBox.setValue(2)
    220 
    221         self.setWindowTitle("Painter Paths")
    222 
    223     def fillRuleChanged(self):
    224         rule = self.currentItemData(self.fillRuleComboBox)
    225         for it in self.renderAreas:
    226             it.setFillRule(rule)
    227 
    228     def fillGradientChanged(self):
    229         color1 = self.currentItemData(self.fillColor1ComboBox)
    230         color2 = self.currentItemData(self.fillColor2ComboBox)
    231         for it in self.renderAreas:
    232             it.setFillGradient(color1, color2)
    233 
    234     def penColorChanged(self):
    235         color = self.currentItemData(self.penColorComboBox)
    236         for it in self.renderAreas:
    237             it.setPenColor(color)
    238     
    239     @staticmethod
    240     def populateWithColors(comboBox):
    241         colorNames = QColor.colorNames()
    242         for name in colorNames:
    243             comboBox.addItem(name, QColor(name))
    244     
    245     @staticmethod
    246     def currentItemData(comboBox):
    247         return comboBox.itemData(comboBox.currentIndex(),Qt.UserRole)
    248 
    249 
    250 if __name__ == "__main__":
    251     import sys
    252     app = QApplication(sys.argv)
    253     win = MyWindow()
    254     win.show()
    255     sys.exit(app.exec_())
    View Code
  • 相关阅读:
    weekly review 200812: Tire
    monthly report 200802: between the festival and the happiness
    weekly review 200813: Ill
    Android中的SharedPreferences
    如何使用Github上的开源项目
    Android四大组件
    开发者需知的10类工具
    activity中onResume()的用处
    Redhat 5.4 + ASM + RAW+ Oracle 10g RAC 安装文档
    Oracle 索引扫描的五种类型
  • 原文地址:https://www.cnblogs.com/hhh5460/p/4281587.html
Copyright © 2011-2022 走看看