1#!/usr/bin/env python 2 3 4############################################################################# 5## 6## Copyright (C) 2013 Riverbank Computing Limited. 7## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 8## All rights reserved. 9## 10## This file is part of the examples of PyQt. 11## 12## $QT_BEGIN_LICENSE:BSD$ 13## You may use this file under the terms of the BSD license as follows: 14## 15## "Redistribution and use in source and binary forms, with or without 16## modification, are permitted provided that the following conditions are 17## met: 18## * Redistributions of source code must retain the above copyright 19## notice, this list of conditions and the following disclaimer. 20## * Redistributions in binary form must reproduce the above copyright 21## notice, this list of conditions and the following disclaimer in 22## the documentation and/or other materials provided with the 23## distribution. 24## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor 25## the names of its contributors may be used to endorse or promote 26## products derived from this software without specific prior written 27## permission. 28## 29## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 32## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 34## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 35## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 40## $QT_END_LICENSE$ 41## 42############################################################################# 43 44 45from PyQt5.QtCore import QPoint, QRect, QSize, Qt 46from PyQt5.QtGui import (QBrush, QConicalGradient, QLinearGradient, QPainter, 47 QPainterPath, QPalette, QPen, QPixmap, QPolygon, QRadialGradient) 48from PyQt5.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout, 49 QLabel, QSpinBox, QWidget) 50 51import basicdrawing_rc 52 53 54class RenderArea(QWidget): 55 points = QPolygon([ 56 QPoint(10, 80), 57 QPoint(20, 10), 58 QPoint(80, 30), 59 QPoint(90, 70) 60 ]) 61 62 Line, Points, Polyline, Polygon, Rect, RoundedRect, Ellipse, Arc, Chord, \ 63 Pie, Path, Text, Pixmap = range(13) 64 65 def __init__(self, parent=None): 66 super(RenderArea, self).__init__(parent) 67 68 self.pen = QPen() 69 self.brush = QBrush() 70 self.pixmap = QPixmap() 71 72 self.shape = RenderArea.Polygon 73 self.antialiased = False 74 self.transformed = False 75 self.pixmap.load(':/images/qt-logo.png') 76 77 self.setBackgroundRole(QPalette.Base) 78 self.setAutoFillBackground(True) 79 80 def minimumSizeHint(self): 81 return QSize(100, 100) 82 83 def sizeHint(self): 84 return QSize(400, 200) 85 86 def setShape(self, shape): 87 self.shape = shape 88 self.update() 89 90 def setPen(self, pen): 91 self.pen = pen 92 self.update() 93 94 def setBrush(self, brush): 95 self.brush = brush 96 self.update() 97 98 def setAntialiased(self, antialiased): 99 self.antialiased = antialiased 100 self.update() 101 102 def setTransformed(self, transformed): 103 self.transformed = transformed 104 self.update() 105 106 def paintEvent(self, event): 107 rect = QRect(10, 20, 80, 60) 108 109 path = QPainterPath() 110 path.moveTo(20, 80) 111 path.lineTo(20, 30) 112 path.cubicTo(80, 0, 50, 50, 80, 80) 113 114 startAngle = 30 * 16 115 arcLength = 120 * 16 116 117 painter = QPainter(self) 118 painter.setPen(self.pen) 119 painter.setBrush(self.brush) 120 if self.antialiased: 121 painter.setRenderHint(QPainter.Antialiasing) 122 123 for x in range(0, self.width(), 100): 124 for y in range(0, self.height(), 100): 125 painter.save() 126 painter.translate(x, y) 127 if self.transformed: 128 painter.translate(50, 50) 129 painter.rotate(60.0) 130 painter.scale(0.6, 0.9) 131 painter.translate(-50, -50) 132 133 if self.shape == RenderArea.Line: 134 painter.drawLine(rect.bottomLeft(), rect.topRight()) 135 elif self.shape == RenderArea.Points: 136 painter.drawPoints(RenderArea.points) 137 elif self.shape == RenderArea.Polyline: 138 painter.drawPolyline(RenderArea.points) 139 elif self.shape == RenderArea.Polygon: 140 painter.drawPolygon(RenderArea.points) 141 elif self.shape == RenderArea.Rect: 142 painter.drawRect(rect) 143 elif self.shape == RenderArea.RoundedRect: 144 painter.drawRoundedRect(rect, 25, 25, Qt.RelativeSize) 145 elif self.shape == RenderArea.Ellipse: 146 painter.drawEllipse(rect) 147 elif self.shape == RenderArea.Arc: 148 painter.drawArc(rect, startAngle, arcLength) 149 elif self.shape == RenderArea.Chord: 150 painter.drawChord(rect, startAngle, arcLength) 151 elif self.shape == RenderArea.Pie: 152 painter.drawPie(rect, startAngle, arcLength) 153 elif self.shape == RenderArea.Path: 154 painter.drawPath(path) 155 elif self.shape == RenderArea.Text: 156 painter.drawText(rect, Qt.AlignCenter, 157 "PyQt by\nRiverbank Computing") 158 elif self.shape == RenderArea.Pixmap: 159 painter.drawPixmap(10, 10, self.pixmap) 160 161 painter.restore() 162 163 painter.setPen(self.palette().dark().color()) 164 painter.setBrush(Qt.NoBrush) 165 painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1)) 166 167 168IdRole = Qt.UserRole 169 170class Window(QWidget): 171 def __init__(self): 172 super(Window, self).__init__() 173 174 self.renderArea = RenderArea() 175 176 self.shapeComboBox = QComboBox() 177 self.shapeComboBox.addItem("Polygon", RenderArea.Polygon) 178 self.shapeComboBox.addItem("Rectangle", RenderArea.Rect) 179 self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect) 180 self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse) 181 self.shapeComboBox.addItem("Pie", RenderArea.Pie) 182 self.shapeComboBox.addItem("Chord", RenderArea.Chord) 183 self.shapeComboBox.addItem("Path", RenderArea.Path) 184 self.shapeComboBox.addItem("Line", RenderArea.Line) 185 self.shapeComboBox.addItem("Polyline", RenderArea.Polyline) 186 self.shapeComboBox.addItem("Arc", RenderArea.Arc) 187 self.shapeComboBox.addItem("Points", RenderArea.Points) 188 self.shapeComboBox.addItem("Text", RenderArea.Text) 189 self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap) 190 191 shapeLabel = QLabel("&Shape:") 192 shapeLabel.setBuddy(self.shapeComboBox) 193 194 self.penWidthSpinBox = QSpinBox() 195 self.penWidthSpinBox.setRange(0, 20) 196 self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)") 197 198 penWidthLabel = QLabel("Pen &Width:") 199 penWidthLabel.setBuddy(self.penWidthSpinBox) 200 201 self.penStyleComboBox = QComboBox() 202 self.penStyleComboBox.addItem("Solid", Qt.SolidLine) 203 self.penStyleComboBox.addItem("Dash", Qt.DashLine) 204 self.penStyleComboBox.addItem("Dot", Qt.DotLine) 205 self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine) 206 self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine) 207 self.penStyleComboBox.addItem("None", Qt.NoPen) 208 209 penStyleLabel = QLabel("&Pen Style:") 210 penStyleLabel.setBuddy(self.penStyleComboBox) 211 212 self.penCapComboBox = QComboBox() 213 self.penCapComboBox.addItem("Flat", Qt.FlatCap) 214 self.penCapComboBox.addItem("Square", Qt.SquareCap) 215 self.penCapComboBox.addItem("Round", Qt.RoundCap) 216 217 penCapLabel = QLabel("Pen &Cap:") 218 penCapLabel.setBuddy(self.penCapComboBox) 219 220 self.penJoinComboBox = QComboBox() 221 self.penJoinComboBox.addItem("Miter", Qt.MiterJoin) 222 self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin) 223 self.penJoinComboBox.addItem("Round", Qt.RoundJoin) 224 225 penJoinLabel = QLabel("Pen &Join:") 226 penJoinLabel.setBuddy(self.penJoinComboBox) 227 228 self.brushStyleComboBox = QComboBox() 229 self.brushStyleComboBox.addItem("Linear Gradient", 230 Qt.LinearGradientPattern) 231 self.brushStyleComboBox.addItem("Radial Gradient", 232 Qt.RadialGradientPattern) 233 self.brushStyleComboBox.addItem("Conical Gradient", 234 Qt.ConicalGradientPattern) 235 self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern) 236 self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern) 237 self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern) 238 self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern) 239 self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern) 240 self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern) 241 self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern) 242 self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern) 243 self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern) 244 self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern) 245 self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern) 246 self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern) 247 self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern) 248 self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern) 249 self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern) 250 self.brushStyleComboBox.addItem("None", Qt.NoBrush) 251 252 brushStyleLabel = QLabel("&Brush Style:") 253 brushStyleLabel.setBuddy(self.brushStyleComboBox) 254 255 otherOptionsLabel = QLabel("Other Options:") 256 self.antialiasingCheckBox = QCheckBox("&Antialiasing") 257 self.transformationsCheckBox = QCheckBox("&Transformations") 258 259 self.shapeComboBox.activated.connect(self.shapeChanged) 260 self.penWidthSpinBox.valueChanged.connect(self.penChanged) 261 self.penStyleComboBox.activated.connect(self.penChanged) 262 self.penCapComboBox.activated.connect(self.penChanged) 263 self.penJoinComboBox.activated.connect(self.penChanged) 264 self.brushStyleComboBox.activated.connect(self.brushChanged) 265 self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased) 266 self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed) 267 268 mainLayout = QGridLayout() 269 mainLayout.setColumnStretch(0, 1) 270 mainLayout.setColumnStretch(3, 1) 271 mainLayout.addWidget(self.renderArea, 0, 0, 1, 4) 272 mainLayout.setRowMinimumHeight(1, 6) 273 mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight) 274 mainLayout.addWidget(self.shapeComboBox, 2, 2) 275 mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight) 276 mainLayout.addWidget(self.penWidthSpinBox, 3, 2) 277 mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight) 278 mainLayout.addWidget(self.penStyleComboBox, 4, 2) 279 mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight) 280 mainLayout.addWidget(self.penCapComboBox, 5, 2) 281 mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight) 282 mainLayout.addWidget(self.penJoinComboBox, 6, 2) 283 mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight) 284 mainLayout.addWidget(self.brushStyleComboBox, 7, 2) 285 mainLayout.setRowMinimumHeight(8, 6) 286 mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight) 287 mainLayout.addWidget(self.antialiasingCheckBox, 9, 2) 288 mainLayout.addWidget(self.transformationsCheckBox, 10, 2) 289 self.setLayout(mainLayout) 290 291 self.shapeChanged() 292 self.penChanged() 293 self.brushChanged() 294 self.antialiasingCheckBox.setChecked(True) 295 296 self.setWindowTitle("Basic Drawing") 297 298 def shapeChanged(self): 299 shape = self.shapeComboBox.itemData(self.shapeComboBox.currentIndex(), 300 IdRole) 301 self.renderArea.setShape(shape) 302 303 def penChanged(self): 304 width = self.penWidthSpinBox.value() 305 style = Qt.PenStyle(self.penStyleComboBox.itemData( 306 self.penStyleComboBox.currentIndex(), IdRole)) 307 cap = Qt.PenCapStyle(self.penCapComboBox.itemData( 308 self.penCapComboBox.currentIndex(), IdRole)) 309 join = Qt.PenJoinStyle(self.penJoinComboBox.itemData( 310 self.penJoinComboBox.currentIndex(), IdRole)) 311 312 self.renderArea.setPen(QPen(Qt.blue, width, style, cap, join)) 313 314 def brushChanged(self): 315 style = Qt.BrushStyle(self.brushStyleComboBox.itemData( 316 self.brushStyleComboBox.currentIndex(), IdRole)) 317 318 if style == Qt.LinearGradientPattern: 319 linearGradient = QLinearGradient(0, 0, 100, 100) 320 linearGradient.setColorAt(0.0, Qt.white) 321 linearGradient.setColorAt(0.2, Qt.green) 322 linearGradient.setColorAt(1.0, Qt.black) 323 self.renderArea.setBrush(QBrush(linearGradient)) 324 elif style == Qt.RadialGradientPattern: 325 radialGradient = QRadialGradient(50, 50, 50, 70, 70) 326 radialGradient.setColorAt(0.0, Qt.white) 327 radialGradient.setColorAt(0.2, Qt.green) 328 radialGradient.setColorAt(1.0, Qt.black) 329 self.renderArea.setBrush(QBrush(radialGradient)) 330 elif style == Qt.ConicalGradientPattern: 331 conicalGradient = QConicalGradient(50, 50, 150) 332 conicalGradient.setColorAt(0.0, Qt.white) 333 conicalGradient.setColorAt(0.2, Qt.green) 334 conicalGradient.setColorAt(1.0, Qt.black) 335 self.renderArea.setBrush(QBrush(conicalGradient)) 336 elif style == Qt.TexturePattern: 337 self.renderArea.setBrush(QBrush(QPixmap(':/images/brick.png'))) 338 else: 339 self.renderArea.setBrush(QBrush(Qt.green, style)) 340 341 342if __name__ == '__main__': 343 344 import sys 345 346 app = QApplication(sys.argv) 347 window = Window() 348 window.show() 349 sys.exit(app.exec_()) 350