【说明】
好吧,坦白从宽,我是Qt扒手(不要鄙视我)。这是我根据qt官网提供的C++版本的例子(http://doc.qt.io/qt-5/qtwidgets-painting-basicdrawing-example.html),改编而成的Python版本。
由于本人没有C++基础,其难度之大,自不待言。
不过,还是毛主席说的好:道路是艰难的,结果是光明的:)
本文基于 win7 + Python3.4 + PyQt5 环境
【效果图】
对比原C++的界面:
【源代码】
1 # File: Basic Draw Example.py 2 # Author: Robin 3 # Date: 2015.2.9 4 # C++: http://doc.qt.io/qt-5/qtwidgets-painting-basicdrawing-example.html 5 6 from PyQt5.QtCore import * 7 from PyQt5.QtGui import * 8 from PyQt5.QtWidgets import * 9 10 class RenderArea(QWidget): 11 Shape = range(13) 12 (Line, Points, Polyline, Polygon, Rect, RoundedRect, 13 Ellipse, Arc, Chord, Pie, Path, Text, Pixmap) = Shape 14 15 def __init__(self, parent=None): 16 super(RenderArea, self).__init__(parent) 17 18 self.shape = self.Polygon 19 self.pen = Qt.NoPen 20 self.brush = Qt.NoBrush 21 self.antialiased = False 22 self.transformed = False 23 self.pixmap = QPixmap() 24 self.pixmap.load("images/qt-logo.png") 25 26 self.setBackgroundRole(QPalette.Base) 27 self.setAutoFillBackground(True) 28 29 def setShape(self, shape): 30 self.shape = shape 31 self.update() 32 33 def setPen(self, pen): 34 self.pen = pen 35 self.update() 36 37 def setBrush(self, brush): 38 self.brush = brush 39 self.update() 40 41 def setAntialiased(self, antialiased): 42 self.antialiased = antialiased 43 self.update() 44 45 def setTransformed(self, transformed): 46 self.transformed = transformed 47 self.update() 48 49 def paintEvent(self, event): 50 points = [QPoint(10, 80), QPoint(20, 10), QPoint(80, 30), QPoint(90, 70)] 51 rect = QRect(10, 20, 80, 60) 52 path = QPainterPath() 53 path.moveTo(20, 80) 54 path.lineTo(20, 30) 55 path.cubicTo(80, 0, 50, 50, 80, 80) 56 startAngle = 20 * 16 57 arcLength = 120 * 16 58 59 painter = QPainter() 60 painter.begin(self) 61 painter.setPen(self.pen) 62 painter.setBrush(self.brush) 63 64 if self.antialiased: 65 painter.setRenderHint(QPainter.Antialiasing, True) 66 for x in range(0, self.width(), 100): 67 for y in range(0, self.height(), 100): 68 painter.save() # 在画笔改变之前保存初始设置,即原点(0,0)处的设置 69 painter.translate(x, y) 70 if self.transformed: 71 painter.translate(50, 50) 72 painter.rotate(60.0) 73 painter.scale(0.6, 0.9) 74 painter.translate(-50, -50) 75 if self.shape == self.Line: 76 painter.drawLine(rect.bottomLeft(), rect.topRight()) 77 elif self.shape == self.Points: 78 painter.drawPoints(QPolygon(points)) 79 elif self.shape == self.Polyline: 80 painter.drawPolyline(QPolygon(points)) 81 elif self.shape == self.Polygon: 82 painter.drawPolygon(QPolygon(points), Qt.WindingFill) 83 elif self.shape == self.Rect: 84 painter.drawRect(rect) 85 elif self.shape == self.RoundedRect: 86 painter.drawRoundedRect(rect, 25, 25, Qt.RelativeSize) 87 elif self.shape == self.Ellipse: 88 painter.drawEllipse(rect) 89 elif self.shape == self.Arc: 90 painter.drawArc(rect, startAngle, arcLength) 91 elif self.shape == self.Chord: 92 painter.drawChord(rect, startAngle, arcLength) 93 elif self.shape == self.Pie: 94 painter.drawPie(rect, startAngle, arcLength) 95 elif self.shape == self.Path: 96 painter.drawPath(path) 97 elif self.shape == self.Text: 98 painter.drawText(rect, Qt.AlignCenter, "Qt by Digia") 99 elif self.shape == self.Pixmap: 100 painter.drawPixmap(10, 10, self.pixmap) 101 painter.restore() # 画完一个之后,将画笔还原到初始设置,即原点(0,0)处的设置。好处是便于计算下一次的坐标变换 102 103 painter.setPen(self.palette().dark().color()) 104 painter.setBrush(Qt.NoBrush) 105 painter.setRenderHint(QPainter.Antialiasing, False) 106 painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1)) 107 painter.end() 108 109 def sizeHint(self): 110 return QSize(400, 200) 111 112 def minimumSizeHint(self): 113 return QSize(100, 100) 114 115 116 class MyWindow(QWidget): 117 118 def __init__(self): 119 super(MyWindow, self).__init__() 120 self.setUi() 121 122 self.shapeChanged() 123 self.penChanged() 124 self.brushChanged() 125 self.checkBox_antialiasing.setChecked(True) 126 127 def setUi(self): 128 self.setWindowTitle("基础绘画例子") 129 self.resize(400,300) 130 self.renderArea = RenderArea() 131 132 self.label_shape = QLabel("Shape:") 133 self.label_penStyle = QLabel("Pen Style:") 134 self.label_brushStyle = QLabel("Brush Style:") 135 self.label_penWidth = QLabel("Pen Width:") 136 self.label_penCap = QLabel("Pen Cap:") 137 self.label_penJoin = QLabel("Pen Join:") 138 139 self.comboBox_shape = QComboBox() 140 self.comboBox_penStyle = QComboBox() 141 self.comboBox_brushStyle = QComboBox() 142 self.spinBox_penWidth = QSpinBox() 143 self.comboBox_penCap = QComboBox() 144 self.comboBox_penJoin = QComboBox() 145 146 self.checkBox_antialiasing = QCheckBox("Antialiasing") 147 self.checkBox_transformations = QCheckBox("Transformations") 148 149 150 gridLayout = QGridLayout() 151 152 gridLayout.setColumnStretch(0, 1) 153 gridLayout.setColumnStretch(1, 4) 154 gridLayout.setColumnStretch(2, 1) 155 gridLayout.setColumnStretch(3, 1) 156 gridLayout.setColumnStretch(4, 4) 157 158 gridLayout.setColumnMinimumWidth(2, 15) 159 gridLayout.setSpacing(15) 160 #gridLayout.setMargin(10) 161 162 gridLayout.addWidget(self.renderArea, 0, 0, 1, 5) 163 gridLayout.addWidget(self.label_shape, 1, 0) 164 gridLayout.addWidget(self.label_penStyle, 2, 0) 165 gridLayout.addWidget(self.label_brushStyle, 3, 0) 166 gridLayout.addWidget(self.checkBox_antialiasing, 4, 0, 1, 2) 167 gridLayout.addWidget(self.comboBox_shape, 1, 1) 168 gridLayout.addWidget(self.comboBox_penStyle, 2, 1) 169 gridLayout.addWidget(self.comboBox_brushStyle, 3, 1) 170 gridLayout.addWidget(self.label_penWidth, 1, 3) 171 gridLayout.addWidget(self.label_penCap, 2, 3) 172 gridLayout.addWidget(self.label_penJoin, 3, 3) 173 gridLayout.addWidget(self.checkBox_transformations, 4, 3, 1, 2) 174 gridLayout.addWidget(self.spinBox_penWidth, 1, 4) 175 gridLayout.addWidget(self.comboBox_penCap, 2, 4) 176 gridLayout.addWidget(self.comboBox_penJoin, 3, 4) 177 178 179 self.setLayout(gridLayout) 180 181 #self.checkBox_antialiasing.setChecked(True) 182 #Line, Points, Polyline, Polygon, Rect, RoundedRect, 183 #Ellipse, Arc, Chord, Pie, Path, Text, Pixmap 184 self.comboBox_shape.addItem('Line') 185 self.comboBox_shape.addItem('Points') 186 self.comboBox_shape.addItem('Polyline') 187 self.comboBox_shape.addItem('Polygon') 188 self.comboBox_shape.addItem('Rect') 189 self.comboBox_shape.addItem('RoundedRect') 190 self.comboBox_shape.addItem('Ellipse') 191 self.comboBox_shape.addItem('Arc') 192 self.comboBox_shape.addItem('Chord') 193 self.comboBox_shape.addItem('Pie') 194 self.comboBox_shape.addItem('Path') 195 self.comboBox_shape.addItem('Text') 196 self.comboBox_shape.addItem('Pixmap') 197 198 self.spinBox_penWidth.setRange(0, 20) 199 #self.spinBox_penWidth.setSpecialValue('0 (cosmetic pen)') 200 201 self.comboBox_penStyle.addItem('Solid',Qt.SolidLine) 202 self.comboBox_penStyle.addItem('Dash',Qt.DashLine) 203 self.comboBox_penStyle.addItem('Dot',Qt.DotLine) 204 self.comboBox_penStyle.addItem('Dash Dot',Qt.DashDotLine) 205 self.comboBox_penStyle.addItem('Dash Dot Dot',Qt.DashDotDotLine) 206 self.comboBox_penStyle.addItem('None',Qt.NoPen) 207 208 self.comboBox_penCap.addItem('Flat',Qt.FlatCap) 209 self.comboBox_penCap.addItem('Square',Qt.SquareCap) 210 self.comboBox_penCap.addItem('Round',Qt.RoundCap) 211 212 self.comboBox_penJoin.addItem('Miter',Qt.MiterJoin) 213 self.comboBox_penJoin.addItem('Bebel',Qt.BevelJoin) 214 self.comboBox_penJoin.addItem('Round',Qt.RoundJoin) 215 216 self.comboBox_brushStyle.addItem('Linear Gradient',Qt.LinearGradientPattern) 217 self.comboBox_brushStyle.addItem('Radial Gradient',Qt.RadialGradientPattern) 218 self.comboBox_brushStyle.addItem('Conical Gradient',Qt.ConicalGradientPattern) 219 self.comboBox_brushStyle.addItem('Texture',Qt.TexturePattern) 220 self.comboBox_brushStyle.addItem('Solid',Qt.SolidPattern) 221 self.comboBox_brushStyle.addItem('Horizontal',Qt.HorPattern) 222 self.comboBox_brushStyle.addItem('Vertical',Qt.VerPattern) 223 self.comboBox_brushStyle.addItem('Cross',Qt.CrossPattern) 224 self.comboBox_brushStyle.addItem('Backward Diagonal',Qt.BDiagPattern) 225 self.comboBox_brushStyle.addItem('Forward Diagonal',Qt.FDiagPattern) 226 self.comboBox_brushStyle.addItem('Diagonal Cross',Qt.DiagCrossPattern) 227 self.comboBox_brushStyle.addItem('Dense 1',Qt.Dense1Pattern) 228 self.comboBox_brushStyle.addItem('Dense 2',Qt.Dense2Pattern) 229 self.comboBox_brushStyle.addItem('Dense 3',Qt.Dense3Pattern) 230 self.comboBox_brushStyle.addItem('Dense 4',Qt.Dense4Pattern) 231 self.comboBox_brushStyle.addItem('Dense 5',Qt.Dense5Pattern) 232 self.comboBox_brushStyle.addItem('Dense 6',Qt.Dense6Pattern) 233 self.comboBox_brushStyle.addItem('Dense 7',Qt.Dense7Pattern) 234 self.comboBox_brushStyle.addItem('None',Qt.NoBrush) 235 236 237 self.comboBox_shape.currentIndexChanged.connect(self.shapeChanged) 238 self.comboBox_brushStyle.currentIndexChanged.connect(self.brushChanged) 239 self.spinBox_penWidth.valueChanged.connect(self.penChanged) 240 self.comboBox_penStyle.currentIndexChanged.connect(self.penChanged) 241 self.comboBox_penCap.currentIndexChanged.connect(self.penChanged) 242 self.comboBox_penJoin.currentIndexChanged.connect(self.penChanged) 243 self.checkBox_antialiasing.clicked.connect(self.renderArea.setAntialiased) 244 self.checkBox_transformations.clicked.connect(self.renderArea.setTransformed) 245 246 def shapeChanged(self): 247 index = self.comboBox_shape.currentIndex() 248 shape = self.renderArea.Shape[index] 249 self.renderArea.setShape(shape) 250 251 def penChanged(self): 252 width = self.spinBox_penWidth.value() 253 style = Qt.PenStyle(self.comboBox_penStyle.itemData(self.comboBox_penStyle.currentIndex(),Qt.UserRole)) 254 cap = Qt.PenCapStyle(self.comboBox_penCap.itemData(self.comboBox_penCap.currentIndex(),Qt.UserRole)) 255 join = Qt.PenJoinStyle(self.comboBox_penJoin.itemData(self.comboBox_penJoin.currentIndex(),Qt.UserRole)) 256 self.renderArea.setPen(QPen(Qt.blue, width, style, cap, join)) 257 258 def brushChanged(self): 259 style = Qt.BrushStyle(self.comboBox_brushStyle.itemData(self.comboBox_brushStyle.currentIndex(),Qt.UserRole)) 260 if style == Qt.LinearGradientPattern: 261 linearGradient = QLinearGradient(0, 0, 100, 100) 262 linearGradient.setColorAt(0.0, Qt.white) 263 linearGradient.setColorAt(0.2, Qt.green) 264 linearGradient.setColorAt(1.0, Qt.black) 265 self.renderArea.setBrush(linearGradient) 266 elif style == Qt.RadialGradientPattern: 267 radialGradient = QRadialGradient(50, 50, 50, 70, 70); 268 radialGradient.setColorAt(0.0, Qt.white) 269 radialGradient.setColorAt(0.2, Qt.green) 270 radialGradient.setColorAt(1.0, Qt.black) 271 self.renderArea.setBrush(radialGradient) 272 elif style == Qt.ConicalGradientPattern: 273 conicalGradient = QConicalGradient(50, 50, 150) 274 conicalGradient.setColorAt(0.0, Qt.white) 275 conicalGradient.setColorAt(0.2, Qt.green) 276 conicalGradient.setColorAt(1.0, Qt.black) 277 self.renderArea.setBrush(conicalGradient) 278 elif style == Qt.TexturePattern: 279 self.renderArea.setBrush(QBrush(QPixmap("images/brick.png"))) 280 else: 281 self.renderArea.setBrush(QBrush(Qt.green, style)) 282 283 284 285 if __name__ == "__main__": 286 import sys 287 app = QApplication(sys.argv) 288 win = MyWindow() 289 win.show() 290 sys.exit(app.exec_())