PyQt5利用QPainter绘制各种图形的实例

yipeiwu_com7年前Python基础

这个例子我做了好几天:

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

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

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

【知识点】

1、关于多个点的使用

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

请看:

# 定义多个点
   points = [QPoint(10, 80), QPoint(20, 10), QPoint(80, 30), QPoint(90, 70)]

   # ===直接使用 points 会报错!=========
   # ...
   elif self.shape == self.Points:
      painter.drawPoints(points)

   elif self.shape == self.Polyline:
      painter.drawPolyline(points)

   elif self.shape == self.Polygon:
      painter.drawPolygon(points, 4)

   # ...

   # ===把 points 用 QPolygon()包裹起来才正确!=========
   # ...
   elif self.shape == self.Points:
      painter.drawPoints(QPolygon(points))

   elif self.shape == self.Polyline:
      painter.drawPolyline(QPolygon(points))

   elif self.shape == self.Polygon:
      painter.drawPolygon(QPolygon(points), 4)

   # ...

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

【效果图】

【资源】

//files.jb51.net/file_images/article/201710/brick.png
//files.jb51.net/file_images/article/201710/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_()

以上这篇PyQt5利用QPainter绘制各种图形的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

Python实现股市信息下载的方法

本文实例讲述了Python实现股市信息下载的方法。分享给大家供大家参考。具体如下: 该程序下载来自yahoo财经的股市信息。 import urllib def getURL(url...

Django之使用celery和NGINX生成静态页面实现性能优化

Django之使用celery和NGINX生成静态页面实现性能优化

性能优化原理: 当我们要给client浏览器返回一个页面时,我们需要去数据库查询数据并将数据和基本页面模板渲染形成页面返回给客户端,但如果每一个用户访问时都去查询一次首页的的数据时,当日...

通过Pandas读取大文件的实例

当数据文件过大时,由于计算机内存有限,需要对大文件进行分块读取: import pandas as pd f = open('E:/学习相关/Python/数据样例/用户侧数据/te...

Python button选取本地图片并显示的实例

从本地文件夹中选取一张图片并在canvas上显示 from tkinter import * from tkinter import filedialog from PIL impo...

python中set()函数简介及实例解析

set函数也是python内置函数的其中一个,属于比较基础的函数。其具体介绍和使用方法,下面进行介绍。 set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算...