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

简介: 【说明】     好吧,坦白从宽,我是Qt扒手(不要鄙视我)。这是我根据qt官网提供的C++版本的例子(http://doc.qt.io/qt-5/qtwidgets-painting-basicdrawing-example.html),改编而成的Python版本。

 

【说明】

    好吧,坦白从宽,我是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\nDigia")
 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_())
View Code

 

目录
相关文章
|
小程序 API 数据安全/隐私保护
github短视频去除水印项目Douyin_TikTok_Download_API介绍
当下正值短视频盛行的时代。在我们浏览短视频的同时,经常能发现一些精美的图片、引人入胜的文案以及吸引眼球的视频,想要将它们保存到本地。然而,保存下来的图片或视频通常伴随着不太愉悦的水印,这显著降低了使用体验。因此,我时常思考是否存在途径能够下载一些无水印的图片。虽然有许多小程序等可以保存无水印的图片或视频,但它们往往伴随着一些令人不悦的广告或付费等。今天,在浏览 GitHub 时偶然发现了一个开源项目,名为“Douyin_TikTok_Download_API”,它能够满足我们的需求。在本文中,我将详细介绍这个项目,并分享如何进行部署和使用。
1673 1
github短视频去除水印项目Douyin_TikTok_Download_API介绍
|
边缘计算 开发框架 人工智能
C#/.NET/.NET Core优秀项目和框架2024年8月简报
C#/.NET/.NET Core优秀项目和框架2024年8月简报
229 0
|
数据采集 测试技术 数据安全/隐私保护
Playwright测试中避免使用no-wait-for-timeout的原因
在Web应用自动化测试中,Playwright作为首选框架,其稳定性至关重要。不当使用`no-wait-for-timeout`会导致测试结果不稳定、不符合真实用户体验且难以调试。推荐采用显式等待策略和合理设置超时时间,结合代理IP技术提高测试成功率和数据多样性。示例代码展示了如何在Playwright中配置代理IP进行数据抓取及分类统计。遵循这些最佳实践可确保测试既可靠又贴近实际用户场景。
792 4
Playwright测试中避免使用no-wait-for-timeout的原因
|
人工智能 算法 机器人
机器人版的斯坦福小镇来了,专为具身智能研究打造
【8月更文挑战第12天】《GRUtopia:城市级具身智能仿真平台》新论文发布,介绍了一款由上海AI实验室主导的大规模3D城市模拟环境——GRUtopia。此平台包含十万级互动场景与大型语言模型驱动的NPC系统,旨在解决具身智能研究中的数据稀缺问题并提供全面的评估工具,为机器人技术的进步搭建重要桥梁。https://arxiv.org/pdf/2407.10943
537 60
|
知识图谱
4种通过LLM进行文本知识图谱的构建方法对比介绍
我们在以前的文章中已经介绍了使用大语言模型将非结构化文本转换为知识图谱。但是对于知识图谱的创建是一个很复杂的过程,比如需要对属性增加限制,创建符合特定主题/模式的图谱,并且有时文档非常大,无法作为单个提示处理,所以在切分后的提示中创建的图谱需要前后一致。
783 0
|
Linux 虚拟化
Mac VMware Fusion(11.5)中设置NAT模式并配置静态IP(Linux为例)
Mac VMware Fusion(11.5)中设置NAT模式并配置静态IP(Linux为例)
3907 0
|
Linux
如何在 Linux 中强制删除目录?
如何在 Linux 中强制删除目录?
1034 0
|
存储 人工智能 数据可视化
手把手教学构建证券知识图谱/知识库(含码源):网页获取信息、设计图谱、Cypher查询、Neo4j关系可视化展示
手把手教学构建证券知识图谱/知识库(含码源):网页获取信息、设计图谱、Cypher查询、Neo4j关系可视化展示
手把手教学构建证券知识图谱/知识库(含码源):网页获取信息、设计图谱、Cypher查询、Neo4j关系可视化展示
|
数据可视化 数据挖掘 Python
缠论技术指标的实现
缠论技术指标的实现需要使用Python编程语言,并结合相关的数据分析库和可视化库。以下是一个简单的示例代码,用于计算股票价格的中枢:
438 0
|
机器学习/深度学习 文字识别 算法
一文看懂增值税发票识别OCR:从技术原理到 API Java 示例代码接入
一文看懂增值税发票识别OCR:从技术原理到 API Java 示例代码接入
1462 0
一文看懂增值税发票识别OCR:从技术原理到 API Java 示例代码接入