PyQt5的绘图系统可用于渲染矢量图、图像和文本。如果想改变或增强已有的控件,或者想从头创建一个自定义控件时,我们就需要在程序中进行图形的绘制。我们可以使用PyQt5提供的绘图API进行绘图操作。
绘图要在paintEvent()方法中实现。在QPainter对象的begin()与end()方法间编写绘图代码。它会在控件或其他图形设备上进行低级的图形绘制。
ps:我在后期使用pyqt绘图的时候遇到无法实时刷新的问题,已解决,希望能帮助到遇到相同问题的人
1 |
<span class="hljs-keyword">self</span>.repaint() |
在需要重画的地方调用QWidget的repaint方法即可,update方法有时不好用绘制文本
我们先以窗体内Unicode文本的绘制为例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<span class="hljs-keyword">import</span> sys <span class="hljs-keyword">from</span> PyQt5.QtWidgets <span class="hljs-keyword">import</span> QWidget, QApplication <span class="hljs-keyword">from</span> PyQt5.QtGui <span class="hljs-keyword">import</span> QPainter, QColor, QFont <span class="hljs-keyword">from</span> PyQt5.QtCore <span class="hljs-keyword">import</span> Qt <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Example</span><span class="hljs-params">(QWidget)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span> super().__init__() self.initUI() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initUI</span><span class="hljs-params">(self)</span>:</span> self.text = <span class="hljs-string">u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\ \u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\ \u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'</span> self.setGeometry(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">280</span>, <span class="hljs-number">170</span>) self.setWindowTitle(<span class="hljs-string">"Draw text"</span>) self.show() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">paintEvent</span><span class="hljs-params">(self, event)</span>:</span> qp = QPainter() qp.begin(self) self.drawText(event, qp) qp.end() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">drawText</span><span class="hljs-params">(self, event, qp)</span>:</span> qp.setPen(QColor(<span class="hljs-number">168</span>, <span class="hljs-number">34</span>, <span class="hljs-number">3</span>)) qp.setFont(QFont(<span class="hljs-string">"Decorative"</span>, <span class="hljs-number">10</span>)) qp.drawText(event.rect(), Qt.AlignCenter, self.text) <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) |
示例中我们绘制了一些西里尔字母,文本是垂直且水平对齐的。
1 2 |
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">paintEvent</span><span class="hljs-params">(self, event)</span>:</span> ... |
绘制工作在paintEvent的方法内部完成。
1 2 3 4 |
qp = QPainter() qp.<span class="hljs-keyword">begin</span>(<span class="hljs-keyword">self</span>) <span class="hljs-keyword">self</span>.drawText(<span class="hljs-keyword">event</span>, qp) qp.<span class="hljs-keyword">end</span>() |
QPainter负责所有的低级绘制工作,在它的begin()与end()间放置了绘图代码。实际的绘制工作由drawText()方法完成。
1 2 |
qp<span class="hljs-class">.setPen</span>(<span class="hljs-function">QColor(<span class="hljs-number">168</span>, <span class="hljs-number">34</span>, <span class="hljs-number">3</span>)</span>) qp<span class="hljs-class">.setFont</span>(<span class="hljs-function">QFont(<span class="hljs-string">'Decorative'</span>, <span class="hljs-number">10</span>)</span>) |
这里我们定义了用于绘制文本的画笔与字体对象。
1 |
qp<span class="hljs-preprocessor">.drawText</span>(event<span class="hljs-preprocessor">.rect</span>(), Qt<span class="hljs-preprocessor">.AlignCenter</span>, self<span class="hljs-preprocessor">.text</span>) |
drawText()会在窗体上进行文本的绘制。通过paint event(绘图事件)的rect()方法得到当前窗体的可绘图区域。
绘制圆点
点是可以绘制的最简单的图形对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<span class="hljs-keyword">import</span> sys, random <span class="hljs-keyword">from</span> PyQt5.QtWidgets <span class="hljs-keyword">import</span> QWidget, QApplication <span class="hljs-keyword">from</span> PyQt5.QtGui <span class="hljs-keyword">import</span> QPainter, QColor, QPen <span class="hljs-keyword">from</span> PyQt5.QtCore <span class="hljs-keyword">import</span> Qt <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Example</span><span class="hljs-params">(QWidget)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span> super().__init__() self.initUI() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initUI</span><span class="hljs-params">(self)</span>:</span> self.setGeometry(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">280</span>, <span class="hljs-number">170</span>) self.setWindowTitle(<span class="hljs-string">"Points"</span>) self.show() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">paintEvent</span><span class="hljs-params">(self, e)</span>:</span> qp =QPainter() qp.begin(self) self.drawPoints(qp) qp.end() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">drawPoints</span><span class="hljs-params">(self, qp)</span>:</span> qp.setPen(Qt.red) size = self.size() <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1000</span>): x = random.randint(<span class="hljs-number">1</span>, size.width()-<span class="hljs-number">1</span>) y = random.randint(<span class="hljs-number">1</span>, size.height()-<span class="hljs-number">1</span>) qp.drawPoint(x, y) <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) |
示例中我们随机画了1000个红点。
1 |
qp<span class="hljs-preprocessor">.setPen</span>(Qt<span class="hljs-preprocessor">.red</span>) |
将画笔设为红色。我们使用了预定义的Qt.red常量
1 |
<span class="hljs-keyword">size</span> = self.<span class="hljs-keyword">size</span>() |
每次调整窗体尺寸都会生成一个paint event。我们可以通过这个event的size()方法得到窗体当前的尺寸。我们将这些点分配到窗体的各个区域。
1 |
qp<span class="hljs-preprocessor">.drawPoint</span>(<span class="hljs-built_in">x</span>, <span class="hljs-built_in">y</span>) |
通过drawPoint()方法绘制圆点。
颜色
颜色是用于表示红绿蓝(RGB)各色值组合体的对象。合法的RGB值在0到255之间。颜色的定义有多种方式,通常用10进制或16进制的数值表示。我们也可以使用RGBA表示,它代表了红色、绿色、蓝色与Alpha通道值。也就是说我们附加了一个表示透明度的信息。Alpha值为255表示完全不透明,为0表示完全透明,也就是说颜色是不可见的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="hljs-keyword">import</span> sys <span class="hljs-keyword">from</span> PyQt5.QtWidgets <span class="hljs-keyword">import</span> QWidget, QApplication <span class="hljs-keyword">from</span> PyQt5.QtGui <span class="hljs-keyword">import</span> QPainter, QColor, QBrush <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Example</span><span class="hljs-params">(QWidget)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span> super().__init__() self.initUI() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initUI</span><span class="hljs-params">(self)</span>:</span> self.setGeometry(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">350</span>, <span class="hljs-number">100</span>) self.setWindowTitle(<span class="hljs-string">"Colours"</span>) self.show() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">paintEvent</span><span class="hljs-params">(self, e)</span>:</span> qp = QPainter() qp.begin(self) self.drawRectangles(qp) qp.end() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">drawRectangles</span><span class="hljs-params">(self, qp)</span>:</span> col = QColor(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>) col.setNamedColor(<span class="hljs-string">"#d4d4d4"</span>) qp.setPen(col) qp.setBrush(QColor(<span class="hljs-number">200</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)) qp.drawRect(<span class="hljs-number">10</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) qp.setBrush(QColor(<span class="hljs-number">255</span>, <span class="hljs-number">80</span>, <span class="hljs-number">0</span>, <span class="hljs-number">160</span>)) qp.drawRect(<span class="hljs-number">130</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) qp.setBrush(QColor(<span class="hljs-number">25</span>, <span class="hljs-number">0</span>, <span class="hljs-number">90</span>, <span class="hljs-number">200</span>)) qp.drawRect(<span class="hljs-number">250</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) |
示例中我们绘制了三个不同颜色的矩形。
1 2 |
<span class="hljs-keyword">color</span> = QColor(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>) <span class="hljs-keyword">color</span>.setNamedColor(<span class="hljs-string">'#d4d4d4'</span>) |
这里我们使用16进制值定义了一个颜色对象。
1 2 |
qp<span class="hljs-preprocessor">.setBrush</span>(QColor(<span class="hljs-number">200</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)) qp<span class="hljs-preprocessor">.drawRect</span>(<span class="hljs-number">10</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) |
我们为QPainter设置了一个笔刷(Bursh)对象并用它绘制了一个矩形。笔刷是用于绘制形状背景的基本图形对象。drawRect()方法接受四个参数,前两个是起点的x,y坐标,后两个是矩形的宽和高。这个方法使用当前的画笔与笔刷对象进行绘制。
QPen(画笔)
QPen是一个基本图形对象。它用于绘制直线,曲线以及矩形、椭圆、多边形或其他图形的轮廓。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
<span class="hljs-keyword">import</span> sys <span class="hljs-keyword">from</span> PyQt5.QtWidgets <span class="hljs-keyword">import</span> QWidget, QApplication <span class="hljs-keyword">from</span> PyQt5.QtGui <span class="hljs-keyword">import</span> QPainter, QColor, QPen <span class="hljs-keyword">from</span> PyQt5.QtCore <span class="hljs-keyword">import</span> Qt <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Example</span><span class="hljs-params">(QWidget)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span> super().__init__() self.initUI() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initUI</span><span class="hljs-params">(self)</span>:</span> self.setGeometry(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">280</span>, <span class="hljs-number">270</span>) self.setWindowTitle(<span class="hljs-string">"Pen styles"</span>) self.show() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">paintEvent</span><span class="hljs-params">(self, e)</span>:</span> qp = QPainter() qp.begin(self) self.drawLines(qp) qp.end() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">drawLines</span><span class="hljs-params">(self, qp)</span>:</span> pen = QPen(Qt.black, <span class="hljs-number">2</span>, Qt.SolidLine) qp.setPen(pen) qp.drawLine(<span class="hljs-number">20</span>, <span class="hljs-number">40</span>, <span class="hljs-number">250</span>, <span class="hljs-number">40</span>) pen.setStyle(Qt.DashLine) qp.setPen(pen) qp.drawLine(<span class="hljs-number">20</span>, <span class="hljs-number">80</span>, <span class="hljs-number">250</span>, <span class="hljs-number">80</span>) pen.setStyle(Qt.DashDotLine) qp.setPen(pen) qp.drawLine(<span class="hljs-number">20</span>, <span class="hljs-number">120</span>, <span class="hljs-number">250</span>, <span class="hljs-number">120</span>) pen.setStyle(Qt.DotLine) qp.setPen(pen) qp.drawLine(<span class="hljs-number">20</span>, <span class="hljs-number">160</span>, <span class="hljs-number">250</span>, <span class="hljs-number">160</span>) pen.setStyle(Qt.DashDotDotLine) qp.setPen(pen) qp.drawLine(<span class="hljs-number">20</span>, <span class="hljs-number">200</span>, <span class="hljs-number">250</span>, <span class="hljs-number">200</span>) pen.setStyle(Qt.CustomDashLine) pen.setDashPattern([<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">4</span>]) qp.setPen(pen) qp.drawLine(<span class="hljs-number">20</span>, <span class="hljs-number">240</span>, <span class="hljs-number">250</span>, <span class="hljs-number">240</span>) <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) |
示例中我们绘制了6条直线。每条直线使用了不同的画笔风格,其中有5个是PyQt5中预定义的,另外我们也自已实现了一个。最后那条线就是用我们自定义的画笔风格所画。
1 |
pen = QPen(Qt<span class="hljs-preprocessor">.black</span>, <span class="hljs-number">2</span>, Qt<span class="hljs-preprocessor">.SolidLine</span>) |
我们创建了一个黑颜色的画笔对象,其宽度为2像素,这样可以看出画笔风格的不同之处。Qt.SolidLine是预定义的一种画笔风格。
1 2 3 |
pen<span class="hljs-preprocessor">.setStyle</span>(Qt<span class="hljs-preprocessor">.CustomDashLine</span>) pen<span class="hljs-preprocessor">.setDashPattern</span>([<span class="hljs-number">1</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">4</span>]) qp<span class="hljs-preprocessor">.setPen</span>(pen) |
这里我们定义了一个画笔风格。我们设置了Qt.CustomDashLine并调用了setDashPattern()方法,它的参数(一个数字列表)定义了一种风格,必须有偶数个数字;其中奇数表示绘制实线,偶数表示留空。数值越大,直线或空白就越大。这里我们定义了1像素的实线,4像素的空白,5像素实线,4像素空白。。。
QBrush(笔刷)
QBrush是一个基本图形对象。它用于绘制矩形、椭圆或多边形等图形的背景。笔刷有三种类型:预定义笔刷、渐变笔刷或纹理图案笔刷。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<span class="hljs-keyword">import</span> sys <span class="hljs-keyword">from</span> PyQt5.QtWidgets <span class="hljs-keyword">import</span> QWidget, QApplication <span class="hljs-keyword">from</span> PyQt5.QtGui <span class="hljs-keyword">import</span> QPainter, QBrush <span class="hljs-keyword">from</span> PyQt5.QtCore <span class="hljs-keyword">import</span> Qt <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Example</span><span class="hljs-params">(QWidget)</span>:</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span><span class="hljs-params">(self)</span>:</span> super().__init__() self.initUI() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">initUI</span><span class="hljs-params">(self)</span>:</span> self.setGeometry(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>, <span class="hljs-number">355</span>, <span class="hljs-number">280</span>) self.setWindowTitle(<span class="hljs-string">"Brushes"</span>) self.show() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">paintEvent</span><span class="hljs-params">(self, e)</span>:</span> qp = QPainter() qp.begin(self) self.drawBrushes(qp) qp.end() <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">drawBrushes</span><span class="hljs-params">(self, qp)</span>:</span> brush = QBrush(Qt.SolidPattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">10</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.Dense1Pattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">130</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.Dense2Pattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">250</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.Dense3Pattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">10</span>, <span class="hljs-number">105</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.DiagCrossPattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">10</span>, <span class="hljs-number">105</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.Dense5Pattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">130</span>, <span class="hljs-number">105</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.Dense6Pattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">250</span>, <span class="hljs-number">105</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.HorPattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">10</span>, <span class="hljs-number">195</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.VerPattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">130</span>, <span class="hljs-number">195</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) brush.setStyle(Qt.BDiagPattern) qp.setBrush(brush) qp.drawRect(<span class="hljs-number">250</span>, <span class="hljs-number">195</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) |
在示例中我们绘制了9个不同的矩形。
1 2 3 |
brush = QBrush(Qt<span class="hljs-preprocessor">.SolidPattern</span>) qp<span class="hljs-preprocessor">.setBrush</span>(brush) qp<span class="hljs-preprocessor">.drawRect</span>(<span class="hljs-number">10</span>, <span class="hljs-number">15</span>, <span class="hljs-number">90</span>, <span class="hljs-number">60</span>) |
我们定义了一个笔刷对象,然后将它设置给QPainter对象,并调用painter的drawRect()方法绘制矩形。
在这部分教程中我们学习了一些基本的图形绘制。
转载请注明:徐自远的乱七八糟小站 » PyQt5教程(九)——绘图