PyQt5利用QPainter绘制各种图形

简介: 这个例子我做了好几天: 1)官网C++的源码,改写成PyQt5版本的代码,好多细节不会转化 2)网上的PyQt的例子根本运行不了 填了无数个坑,结合二者,终于能完成了一个关于绘图的东西。这个过程也掌握了很多新的知识点 【知识点】 1、关于多个点的使用 poitns = [QPoint(1...

这个例子我做了好几天:

1)官网C++的源码,改写成PyQt5版本的代码,好多细节不会转化

2)网上的PyQt的例子根本运行不了

填了无数个坑,结合二者,终于能完成了一个关于绘图的东西。这个过程也掌握了很多新的知识点

【知识点】

1、关于多个点的使用

poitns = [QPoint(10, 80), QPoint(20, 10), QPoint(80, 30), QPoint(90, 70)]

请看:

 1      # 定义多个点
 2      points = [QPoint(10, 80), QPoint(20, 10), QPoint(80, 30), QPoint(90, 70)]
 3 
 4      # ===直接使用 points 会报错!=========
 5      # ...
 6      elif self.shape == self.Points:
 7            painter.drawPoints(points)
 8 
 9      elif self.shape == self.Polyline:
10            painter.drawPolyline(points)
11 
12      elif self.shape == self.Polygon:
13            painter.drawPolygon(points, 4)
14 
15      # ...
16 
17      # ===把 points 用 QPolygon()包裹起来才正确!=========
18      # ...
19      elif self.shape == self.Points:
20            painter.drawPoints(QPolygon(points))
21 
22      elif self.shape == self.Polyline:
23            painter.drawPolyline(QPolygon(points))
24 
25      elif self.shape == self.Polygon:
26            painter.drawPolygon(QPolygon(points), 4)
27 
28      # ...

2、在QDialog窗体中显示QWidget部件

 

【效果图】

【资源】

http://doc.qt.io/qt-5/images/used-in-examples/painting/basicdrawing/images/brick.png

http://doc.qt.io/qt-5/images/used-in-examples/painting/basicdrawing/images/qt-logo.png

【代码】

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class StockDialog(QWidget):
    def __init__(self, parent=None):
        super(StockDialog, self).__init__(parent)
        self.setWindowTitle("利用QPainter绘制各种图形")
        
        mainSplitter = QSplitter(Qt.Horizontal)
        mainSplitter.setOpaqueResize(True)
                  
        frame = QFrame(mainSplitter)
        mainLayout = QGridLayout(frame)
        #mainLayout.setMargin(10)
        mainLayout.setSpacing(6)

        label1=QLabel("形状:")
        label2=QLabel("画笔线宽:")
        label3=QLabel("画笔颜色:")
        label4=QLabel("画笔风格:")
        label5=QLabel("画笔顶端:")
        label6=QLabel("画笔连接点:")
        label7=QLabel("画刷风格:")
        label8=QLabel("画刷颜色:")
    
        self.shapeComboBox = QComboBox()
        self.shapeComboBox.addItem("Line", "Line")
        self.shapeComboBox.addItem("Rectangle", "Rectangle")
        self.shapeComboBox.addItem('Rounded Rectangle','Rounded Rectangle')
        self.shapeComboBox.addItem('Ellipse','Ellipse')
        self.shapeComboBox.addItem('Pie','Pie')
        self.shapeComboBox.addItem('Chord','Chord')
        self.shapeComboBox.addItem('Path','Path')
        self.shapeComboBox.addItem('Polygon','Polygon')
        self.shapeComboBox.addItem('Polyline','Polyline')
        self.shapeComboBox.addItem('Arc','Arc')
        self.shapeComboBox.addItem('Points','Points')
        self.shapeComboBox.addItem('Text','Text')
        self.shapeComboBox.addItem('Pixmap','Pixmap')
        
        self.widthSpinBox = QSpinBox()
        self.widthSpinBox.setRange(0,20)
        
        self.penColorFrame = QFrame()
        self.penColorFrame.setAutoFillBackground(True)
        self.penColorFrame.setPalette(QPalette(Qt.blue))
        self.penColorPushButton = QPushButton("更改")
        
        self.penStyleComboBox = QComboBox()
        self.penStyleComboBox.addItem("Solid",Qt.SolidLine)
        self.penStyleComboBox.addItem('Dash',  Qt.DashLine)
        self.penStyleComboBox.addItem('Dot',  Qt.DotLine)
        self.penStyleComboBox.addItem('Dash Dot',  Qt.DashDotLine)
        self.penStyleComboBox.addItem('Dash Dot Dot',  Qt.DashDotDotLine)
        self.penStyleComboBox.addItem('None',  Qt.NoPen)
        
        self.penCapComboBox = QComboBox()
        self.penCapComboBox.addItem("Flat",Qt.FlatCap)
        self.penCapComboBox.addItem('Square', Qt.SquareCap)
        self.penCapComboBox.addItem('Round', Qt.RoundCap)
        
        self.penJoinComboBox = QComboBox()
        self.penJoinComboBox.addItem("Miter",Qt.MiterJoin)
        self.penJoinComboBox.addItem('Bebel', Qt.BevelJoin)
        self.penJoinComboBox.addItem('Round', Qt.RoundJoin)
        
        self.brushStyleComboBox = QComboBox()
        self.brushStyleComboBox.addItem("Linear Gradient",Qt.LinearGradientPattern)
        self.brushStyleComboBox.addItem('Radial Gradient', Qt.RadialGradientPattern)
        self.brushStyleComboBox.addItem('Conical Gradient', Qt.ConicalGradientPattern)
        self.brushStyleComboBox.addItem('Texture', Qt.TexturePattern)
        self.brushStyleComboBox.addItem('Solid', Qt.SolidPattern)
        self.brushStyleComboBox.addItem('Horizontal', Qt.HorPattern)
        self.brushStyleComboBox.addItem('Vertical', Qt.VerPattern)
        self.brushStyleComboBox.addItem('Cross', Qt.CrossPattern)
        self.brushStyleComboBox.addItem('Backward Diagonal', Qt.BDiagPattern)
        self.brushStyleComboBox.addItem('Forward Diagonal', Qt.FDiagPattern)
        self.brushStyleComboBox.addItem('Diagonal Cross', Qt.DiagCrossPattern)
        self.brushStyleComboBox.addItem('Dense 1', Qt.Dense1Pattern)
        self.brushStyleComboBox.addItem('Dense 2', Qt.Dense2Pattern)
        self.brushStyleComboBox.addItem('Dense 3', Qt.Dense3Pattern)
        self.brushStyleComboBox.addItem('Dense 4', Qt.Dense4Pattern)
        self.brushStyleComboBox.addItem('Dense 5', Qt.Dense5Pattern)
        self.brushStyleComboBox.addItem('Dense 6', Qt.Dense6Pattern)
        self.brushStyleComboBox.addItem('Dense 7', Qt.Dense7Pattern)
        self.brushStyleComboBox.addItem('None', Qt.NoBrush)
        
        self.brushColorFrame = QFrame()
        self.brushColorFrame.setAutoFillBackground(True)
        self.brushColorFrame.setPalette(QPalette(Qt.green))
        self.brushColorPushButton = QPushButton("更改")
                                                              
        labelCol=0
        contentCol=1
        
        #建立布局
        mainLayout.addWidget(label1,1,labelCol)
        mainLayout.addWidget(self.shapeComboBox,1,contentCol)
        mainLayout.addWidget(label2,2,labelCol)
        mainLayout.addWidget(self.widthSpinBox,2,contentCol)
        mainLayout.addWidget(label3,4,labelCol)
        mainLayout.addWidget(self.penColorFrame,4,contentCol)
        mainLayout.addWidget(self.penColorPushButton,4,3)
        mainLayout.addWidget(label4,6,labelCol)
        mainLayout.addWidget(self.penStyleComboBox,6,contentCol)
        mainLayout.addWidget(label5,8,labelCol)
        mainLayout.addWidget(self.penCapComboBox,8,contentCol)
        mainLayout.addWidget(label6,10,labelCol)
        mainLayout.addWidget(self.penJoinComboBox,10,contentCol)
        mainLayout.addWidget(label7,12,labelCol)
        mainLayout.addWidget(self.brushStyleComboBox,12,contentCol)
        mainLayout.addWidget(label8,14,labelCol)
        mainLayout.addWidget(self.brushColorFrame,14,contentCol)
        mainLayout.addWidget(self.brushColorPushButton,14,3)
        mainSplitter1 = QSplitter(Qt.Horizontal)
        mainSplitter1.setOpaqueResize(True)
        
        stack1 = QStackedWidget()
        stack1.setFrameStyle(QFrame.Panel|QFrame.Raised)
        self.area = PaintArea()
        stack1.addWidget(self.area)        
        frame1 = QFrame(mainSplitter1)
        mainLayout1 = QVBoxLayout(frame1)
        #mainLayout1.setMargin(10)
        mainLayout1.setSpacing(6)
        mainLayout1.addWidget(stack1)

        layout = QGridLayout(self)
        layout.addWidget(mainSplitter1,0,0)
        layout.addWidget(mainSplitter,0,1)
        self.setLayout(layout)
        
        #信号和槽函数
        self.shapeComboBox.activated.connect(self.slotShape)
        self.widthSpinBox.valueChanged.connect(self.slotPenWidth)
        self.penColorPushButton.clicked.connect(self.slotPenColor)
        self.penStyleComboBox.activated.connect(self.slotPenStyle)
        self.penCapComboBox.activated.connect(self.slotPenCap)
        self.penJoinComboBox.activated.connect(self.slotPenJoin)
        self.brushStyleComboBox.activated.connect(self.slotBrush)
        self.brushColorPushButton.clicked.connect(self.slotBrushColor)
        
        self.slotShape(self.shapeComboBox.currentIndex())
        self.slotPenWidth(self.widthSpinBox.value())
        self.slotBrush(self.brushStyleComboBox.currentIndex())        
        
    def slotShape(self,value):
        shape =  self.area.Shape[value]
        self.area.setShape(shape)
    
    def slotPenWidth(self,value):
        color = self.penColorFrame.palette().color(QPalette.Window)
        style = Qt.PenStyle(self.penStyleComboBox.itemData(self.penStyleComboBox.currentIndex(),Qt.UserRole))
        cap = Qt.PenCapStyle(self.penCapComboBox.itemData(self.penCapComboBox.currentIndex(),Qt.UserRole))
        join = Qt.PenJoinStyle(self.penJoinComboBox.itemData(self.penJoinComboBox.currentIndex(),Qt.UserRole))
        self.area.setPen(QPen(color,value,style,cap,join))
    
    def slotPenStyle(self,value):
        self.slotPenWidth(value)
    
    def slotPenCap(self,value):
        self.slotPenWidth(value)
    
    def slotPenJoin(self,value):
        self.slotPenWidth(value)
    
    def slotPenColor(self):
        color = QColorDialog.getColor(Qt.blue)
        self.penColorFrame.setPalette(QPalette(color))
        self.area.setPen(QPen(color))
        
    def slotBrushColor(self):
        color = QColorDialog.getColor(Qt.blue)
        self.brushColorFrame.setPalette(QPalette(color))
        self.slotBrush(self.brushStyleComboBox.currentIndex())
    
    def slotBrush(self,value):
        color = self.brushColorFrame.palette().color(QPalette.Window)
        style = Qt.BrushStyle(self.brushStyleComboBox.itemData(value,Qt.UserRole))
        
        if(style == Qt.LinearGradientPattern):
            linearGradient = QLinearGradient(0,0,400,400)
            linearGradient.setColorAt(0.0,Qt.white)
            linearGradient.setColorAt(0.2,color)
            linearGradient.setColorAt(1.0,Qt.black)
            self.area.setBrush(linearGradient)
        elif style ==Qt.RadialGradientPattern:
            radialGradient = QRadialGradient(200, 200, 80, 70, 70);
            radialGradient.setColorAt(0.0, Qt.white)
            radialGradient.setColorAt(0.2, Qt.green)
            radialGradient.setColorAt(1.0, Qt.black)
            self.area.setBrush(radialGradient)
        elif(style == Qt.ConicalGradientPattern):
            conicalGradient = QConicalGradient(200,200,30)
            conicalGradient.setColorAt(0.0,Qt.white)
            conicalGradient.setColorAt(0.2,color)
            conicalGradient.setColorAt(1.0,Qt.black)
            self.area.setBrush(conicalGradient)
        elif(style == Qt.TexturePattern):
            self.area.setBrush(QBrush(QPixmap("images/brick.png")))
        else:
            self.area.setBrush(QBrush(color,style))
        
    
class PaintArea(QWidget):
    def __init__(self):
        super(PaintArea,self).__init__()
        self.Shape = ["Line","Rectangle", 'Rounded Rectangle', "Ellipse", "Pie", 'Chord', 
    "Path","Polygon", "Polyline", "Arc", "Points", "Text", "Pixmap"]
        self.setPalette(QPalette(Qt.white))
        self.setAutoFillBackground(True)
        self.setMinimumSize(400,400)
        self.pen = QPen()
        self.brush = QBrush()        
    
    def setShape(self,s):
        self.shape = s
        self.update()
        
    def setPen(self,p):
        self.pen = p
        self.update()
    
    def setBrush(self,b):
        self.brush = b
        self.update()
    
    def paintEvent(self,QPaintEvent):
        p = QPainter(self)
        p.setPen(self.pen)
        p.setBrush(self.brush)
        
        rect = QRect(50,100,300,200) 
        points = [QPoint(150,100),QPoint(300,150),QPoint(350,250),QPoint(100,300)]
        startAngle = 30 * 16
        spanAngle = 120 * 16
        
        path = QPainterPath();
        path.addRect(150,150,100,100)
        path.moveTo(100,100)
        path.cubicTo(300,100,200,200,300,300)
        path.cubicTo(100,300,200,200,100,100)
        
        if self.shape == "Line":
            p.drawLine(rect.topLeft(),rect.bottomRight())
        elif self.shape == "Rectangle":
            p.drawRect(rect)
        elif self.shape == 'Rounded Rectangle':
            p.drawRoundedRect(rect, 25, 25, Qt.RelativeSize)
        elif self.shape == "Ellipse":
            p.drawEllipse(rect)
        elif self.shape == "Polygon":
            p.drawPolygon(QPolygon(points),Qt.WindingFill)
        elif self.shape == "Polyline":
            p.drawPolyline(QPolygon(points))
        elif self.shape == "Points":
            p.drawPoints(QPolygon(points))
        elif self.shape == "Pie":
            p.drawPie(rect, startAngle, spanAngle)
        elif self.shape == "Arc":
            p.drawArc(rect,startAngle,spanAngle)
        elif self.shape == "Chord":
            p.drawChord(rect, startAngle, spanAngle)
        elif self.shape == "Path":
            p.drawPath(path)
        elif self.shape == "Text":
            p.drawText(rect,Qt.AlignCenter,"Hello Qt!")
        elif self.shape == "Pixmap":
            p.drawPixmap(150,150,QPixmap("images/qt-logo.png"))
        
if __name__=='__main__':
    app = QApplication(sys.argv)
    form = StockDialog()
    form.show()
    app.exec_()

 

(罗兵 作于2015.02.05     01:58)

 

目录
相关文章
|
编解码 Linux
Linux MIPI DSI驱动调试笔记-LCD时序参数配置(三)
Linux MIPI DSI驱动调试笔记-LCD时序参数配置(三)
1743 0
|
前端开发
el-transfer 数据量过大加载慢卡顿解决办法:el-transfer虚拟滚动懒加载的实现
el-transfer 数据量过大加载慢卡顿解决办法:el-transfer虚拟滚动懒加载的实现
973 0
|
编译器 Linux C语言
【CMake install目录解析】CMake 深度解析:实现精准、高效的项目构建与安装
【CMake install目录解析】CMake 深度解析:实现精准、高效的项目构建与安装
1196 0
|
5月前
|
文字识别 BI
【工具教程】批量PDF和图片OCR识别指定区域文字自动改图片名字,多个区域一次性批量识别改名批量重命名
本内容介绍了一款用于企业档案、医院病历及办公文件管理的图片和PDF文字识别工具。通过框选识别区域,软件可批量提取关键信息,实现文件重命名或导出为表格,极大提升管理效率。支持图片与PDF两种模式,操作简单,适用于合同、病历、报告等场景。提供详细步骤指导,包含区域设置、文件导入、批量处理及结果校验等功能。
740 8
|
关系型数据库 MySQL
mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file
mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file
831 0
|
6月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
8月前
|
存储 搜索推荐 大数据
数据大爆炸:解析大数据的起源及其对未来的启示
数据大爆炸:解析大数据的起源及其对未来的启示
395 15
数据大爆炸:解析大数据的起源及其对未来的启示
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
VMB:中科院联合多所高校推出多模态音乐生成框架,能够通过文本、图像和视频等多种输入生成音乐
VMB(Visuals Music Bridge)是由中科院联合多所高校机构推出的多模态音乐生成框架,能够从文本、图像和视频等多种输入模态生成音乐。该框架通过文本桥接和音乐桥接解决了数据稀缺、跨模态对齐弱和可控性有限的问题。
309 7
VMB:中科院联合多所高校推出多模态音乐生成框架,能够通过文本、图像和视频等多种输入生成音乐
|
10月前
|
SQL 分布式计算 Java
【赵渝强老师】Hive的体系架构
Hive是基于Hadoop的数据仓库平台,提供SQL-like的HQL语言进行数据分析,无需编写复杂的Java代码。Hive支持丰富的数据模型,可将SQL语句转换为MapReduce任务在Yarn上运行,底层依赖HDFS存储数据。Hive可通过CLI、JDBC和Web界面执行SQL查询。
376 2
|
10月前
|
JavaScript 前端开发 持续交付
构建现代Web应用:Vue.js与Node.js的完美结合
【10月更文挑战第22天】随着互联网技术的快速发展,Web应用已经成为了人们日常生活和工作的重要组成部分。前端技术和后端技术的不断创新,为Web应用的构建提供了更多可能。在本篇文章中,我们将探讨Vue.js和Node.js这两大热门技术如何完美结合,构建现代Web应用。
271 4