Python畫圖小案例之多啦A夢叮當貓超詳細註釋
一步步教你怎麼用Python畫多啦A夢叮當貓,進一步熟悉Python的基礎畫圖操作。
分析:叮當貓由頭、臉、眼、眼珠、鼻子、嘴、胡子、項帶、鈴當、身子、圍嘴、手臂、手、腳組成。 其中:頭、臉、眼、眼珠、鼻子、嘴、胡子組成一個部件;其餘元件組成一個部件。廢話不多說,上代碼。
希望您給個關註給個贊,也算對我們的支持瞭。
import math import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class Shape: # 圖形基類(叮當貓各部件(形狀)共有的屬性) def __init__(self, qp, QRect, QColor=QColor("#07bbee")): # 構造方法參數:形狀,位置坐標,顏色, color="#07bbee" self.qp = qp #qpainter()的實例 self.rect = QRect # 坐標(x1, y1, x2, y2) self.color = QColor #顏色 self.qp.setPen(QPen(Qt.black, 3)) #邊線 class Liner: #直線類 def __init__(self, qp, QRect): self.qp = qp self.rect = QRect self.width = 1 class Arc: #弧線類 def __init__(self, qp, QRect, startAngle, spanAngle): self.qp = qp self.rect = QRect self.startAngle = startAngle self.spanAngle = spanAngle class eyeball(Shape): #眼珠 def draw(self): self.qp.setBrush(self.color) #設置畫刷 self.qp.drawEllipse(self.rect) #畫圓形x,y,w,h 120, 25, 160, 160 class mouth(Arc): def draw(self): self.qp.drawArc(self.rect,self.startAngle,self.spanAngle) #後面兩個參數分別為 起始角與跨度角 class beard(Liner): #中央豎線 def draw(self): self.qp.drawLine(self.rect) class Beards: #胡須組合 def __init__(self, qp, start_point): # w,h 寬、高 self.qp = qp # self.start_point = start_point #起始坐標 self.bd0 = beard(self.qp, self.bd0_cacu()) self.bd1 = beard(self.qp, self.bd1_cacu()) self.bd2 = beard(self.qp, self.bd2_cacu()) self.bd00 = beard(self.qp, self.bd00_cacu()) self.bd11 = beard(self.qp, self.bd11_cacu()) self.bd22 = beard(self.qp, self.bd22_cacu()) def draw(self): # 繪制 self.bd1.draw() self.bd0.draw() self.bd2.draw() self.bd11.draw() self.bd00.draw() self.bd22.draw() def bd0_cacu(self): # 計算胡須的坐標 x1 = self.start_point[0] - 40 y1 = self.start_point[1] - 5 x2 = x1 - 58 y2 = y1 - 20 return QLineF(x1, y1, x2, y2) def bd1_cacu(self): # 計算中間胡須的坐標 x1 = self.start_point[0] - 40 y1 = self.start_point[1] + 5 x2 = x1 -65 y2 = y1 return QLineF(x1, y1, x2, y2) def bd2_cacu(self): # 計算胡須的坐標 x1 = self.start_point[0] - 40 y1 = self.start_point[1] + 15 x2 = x1 -58 y2 = y1 + 20 return QLineF(x1, y1, x2, y2) def bd00_cacu(self): # 計算胡須的坐標 x1 = self.start_point[0] + 40 y1 = self.start_point[1] - 5 x2 = x1 + 58 y2 = y1 - 20 return QLineF(x1, y1, x2, y2) def bd11_cacu(self): # 計算胡須的坐標 x1 = self.start_point[0] + 40 y1 = self.start_point[1] + 5 x2 = x1 + 65 y2 = y1 return QLineF(x1, y1, x2, y2) def bd22_cacu(self): # 計算胡須的坐標 x1 = self.start_point[0] + 40 y1 = self.start_point[1] + 15 x2 = x1 + 58 y2 = y1 + 20 return QLineF(x1, y1, x2, y2) class head(Shape): # 頭 def draw(self): ##實例:x1,y1,x2,y2,即漸變的起始點和終止點 linearGradient = QLinearGradient(420, 0, 100, 280) #線性漸變色的效果,以整個圖形區間為100%, #分成多段設置顏色,各顏色按百分比分配。 linearGradient.setColorAt(0.1, Qt.white) #10%處白色 linearGradient.setColorAt(0.2, self.color) #60%處綠色 #07bbee linearGradient.setColorAt(0.8, self.color) #60%處綠色 #07bbee linearGradient.setColorAt(1.0, Qt.black) #100%處黑色 self.qp.setBrush(linearGradient) #設置畫刷 # self.qp.setBrush(self.color) # qp.drawRoundedRect(120, 25, 160, 160, 40, 40, Qt.RelativeSize) #畫圓角矩形x1,y1,x2,y2,圓角的角度 self.qp.drawEllipse(self.rect) #畫圓形x,y,w,h 120, 25, 160, 160 class nose(Shape): #鼻子 def draw(self): RadialGradient = QRadialGradient(265, 144, 6, 265, 144) #輻射漸變 #參數分別為中心坐標,半徑長度和焦點坐標, #如果需要對稱那麼中心坐標和焦點坐標要一致 #c93300 #輻射漸變色的效果,以整個圖形區間為100%, #分成多段設置顏色,各顏色按百分比分配。 RadialGradient.setColorAt(0.0, Qt.white) #10%處白色 RadialGradient.setColorAt(1.0, self.color) #60%處綠色 #07bbee # RadialGradient.setColorAt(1.0, Qt.black) #100%處黑色 self.qp.setPen(QPen(Qt.black, 2)) #邊線 self.qp.setBrush(RadialGradient) #設置畫刷 self.qp.drawRoundedRect(self.rect, 80, 80, Qt.RelativeSize) #畫圓角矩形x,y,w,h,圓角的角度 class face(Shape): def draw(self): self.qp.setPen(Qt.NoPen) #無邊線 self.qp.setBrush(self.color) #設置畫刷 self.qp.drawEllipse(self.rect) #畫圓形x,y,w,h 120, 25, 160, 160 class eye(Shape): #眼框 def draw(self): self.qp.setBrush(self.color) #設置畫刷 self.qp.drawRoundedRect(self.rect, 90, 90, Qt.RelativeSize) #畫圓角矩形x1,y1,x2,y2,圓角的角度 class Heads: # 頭部整體(組合頭、臉、眼、鼻、嘴、胡子) def __init__(self, qp, start_point,w, h): # w,h是帽子的寬、高 self.qp = qp # self.start_point = start_point #起始坐標 self.w = w self.h = h self.hd = head(self.qp, self.hd_cacu(), QColor('#07bbee')) # 例化頭 self.fc = face(self.qp, self.fc_cacu(), Qt.white) #臉 self.nos = nose(self.qp, self.nos_cacu(), QColor("#c93300")) #鼻子 self.eye0 = eye(self.qp, self.ey0_cacu(), Qt.white) # 實例化眼0 self.eye1 = eye(self.qp, self.ey1_cacu(), Qt.white) #眼1 self.bds = Beards(self.qp, (260, 185)) #胡須組合的起始位置 self.bd = beard(self.qp, self.bd_cacu()) #中央豎線 self.mt = mouth(self.qp, self.mt_cacu(), 230 * 16, 80 * 16) #弧線的起始角度, 弧線角度(角度*16) self.mt2 = mouth(self.qp, self.mt2_cacu(), 230 * 16, 80 * 16) #弧線的起始角度, 弧線角度(角度*16) self.eb0 = eyeball(self.qp, self.eb0_cacu(), Qt.black) #眼珠0 self.eb1 = eyeball(self.qp, self.eb1_cacu(), Qt.black) #眼珠1 def draw(self): # 繪制 self.hd.draw() #調用頭方法繪制 self.fc.draw() # 調用臉方法繪制 self.nos.draw() # 調用底部方法繪制 self.eye0.draw() self.eye1.draw() self.bds.draw() self.bd.draw() #調用頭方法繪制 self.mt.draw() self.mt2.draw() self.eb0.draw() #眼珠 self.eb1.draw() def eb0_cacu(self): # 計算眼珠的坐標 x = self.start_point[0] + self.w / 2 - 25 y = self.start_point[1] + 70 w = 12 h = 12 return QRect(x, y, w, h) def eb1_cacu(self): # 計算眼珠的坐標 x = self.start_point[0] + self.w / 2 + 15 y = self.start_point[1] + 70 w = 12 h = 12 return QRect(x, y, w, h) def bd_cacu(self): # 計算中央豎線的坐標 x1 = self.start_point[0] + self.w / 2 y1 = self.start_point[1] + 135 x2 = x1 y2 = y1 + 95 return QLineF(x1, y1, x2, y2) def mt_cacu(self): # 計算嘴的坐標 x = self.start_point[0] + 50 y = self.start_point[1] + 45 w = 220 h = 186 return QRect(x, y, w, h) def mt2_cacu(self): # 計算嘴的坐標 x = self.start_point[0] + 60 y = self.start_point[1] + 49 w = 200 h = 185 return QRect(x, y, w, h) def nos_cacu(self): # 計算鼻子的坐標 # r = self.h / 3 / 2 x = self.start_point[0] + self.w /2 -15 y = self.start_point[1] + 105 w = 30 h = 30 return QRect(x, y, w, h) def hd_cacu(self): # 計算頭的坐標 x = self.start_point[0] y = self.start_point[1] w = self.w h = self.h return QRect(x, y, w, h) def fc_cacu(self): # 計算臉的坐標 x = self.start_point[0] + 35 y = self.start_point[1] + 65 w = self.w - 65 h = self.h - 100 return QRect(x, y, w, h) def ey1_cacu(self): # 計算眼1的坐標(圓角矩形) x = self.start_point[0] + self.w / 2 y = self.start_point[1] + 40 w = 70 h = 80 return QRect(x, y, w, h) def ey0_cacu(self): # 計算眼0的坐標(圓角矩形) x = self.start_point[0] + self.w / 2 - 70 y = self.start_point[1] + 40 w = 70 h = 80 return QRect(x, y, w, h) class collar(Shape): #項圈 def draw(self): linearGradient = QLinearGradient(140, 280, 140, 310) #參數分別為中心坐標,半徑長度和焦點坐標, #如果需要對稱那麼中心坐標和焦點坐標要一致 #c93300 #輻射漸變色的效果,以整個圖形區間為100%, #分成多段設置顏色,各顏色按百分比分配。 linearGradient.setColorAt(0.2, QColor("#c40")) #10%處 linearGradient.setColorAt(1.0, QColor("#800400")) # # linearGradient.setColorAt(1.0, Qt.black) #100%處黑色 self.qp.setPen(QPen(Qt.black, 2)) #邊線 self.qp.setBrush(linearGradient) #設置畫刷 self.qpp = QPainterPath() #路徑 self.qpp.moveTo(self.rect[0] + self.rect[2], self.rect[1] + 20) self.qpp.arcTo(self.rect[0] + self.rect[2] - 10, self.rect[1] , 20.0, 20.0, 270.0, 180.0) #(70, 30, R*2, R*2, 0, 180);(70,30)是起始位置,R是半徑,270是起始角度,180是要畫的角度 self.qpp.lineTo(self.rect[0], self.rect[1]) self.qpp.arcTo(self.rect[0]-10, self.rect[1], 20.0, 20.0, 90.0, 180.0) self.qpp.closeSubpath() self.qp.drawPath(self.qpp) class bell(Shape): #鈴鐺 def draw(self): #參數分別為中心坐標,半徑長度和焦點坐標, #如果需要對稱那麼中心坐標和焦點坐標要一致 #c93300 RadialGradient = QRadialGradient(270, 308, 40, 260, 300) #輻射漸變 #輻射漸變色的效果,以整個圖形區間為100%, #分成多段設置顏色,各顏色按百分比分配。 RadialGradient.setColorAt(0.0, QColor("#f9f12a")) #10%處白色 RadialGradient.setColorAt(0.75, QColor("#e9e11a")) #60%處綠色 #07bbee RadialGradient.setColorAt(1.0, QColor("#a9a100")) #100%處黑色 self.qp.setPen(QPen(Qt.black, 2)) #邊線 self.qp.setBrush(RadialGradient) #設置畫刷 self.qp.drawRoundedRect(self.rect, 90, 90, Qt.RelativeSize) #畫圓角矩形x1,y1,x2,y2,圓角的角度 class body(Shape): #身體 def draw(self): self.qp.setPen(QPen(Qt.black, 2)) #邊線 self.qp.setBrush(self.color) #設置畫刷 self.qpp = QPainterPath() #路徑 self.qpp.moveTo(self.rect[0] + 228, self.rect[1] - 15) self.qpp.lineTo(self.rect[0] + 230 + 45, self.rect[1] + 25) self.qpp.lineTo(self.rect[0] + 230 + 20, self.rect[1] + 60) self.qpp.lineTo(self.rect[0] + 230 - 2, self.rect[1] + 40) self.qpp.lineTo(self.rect[0] + 230 - 2, self.rect[1] + 170) self.qpp.arcTo(self.rect[0] + 105,self.rect[1] + 170-10, 20, 20, 0, 180) #中間半圓 self.qpp.lineTo(self.rect[0] -2, self.rect[1] + 170) self.qpp.lineTo(self.rect[0] - 2, self.rect[1] + 40) self.qpp.lineTo(self.rect[0] - 20, self.rect[1] + 60) self.qpp.lineTo(self.rect[0] - 40, self.rect[1] + 25) self.qpp.lineTo(self.rect[0] + 2, self.rect[1] - 14) self.qpp.closeSubpath() self.qp.drawPath(self.qpp) class foot(Shape): #腳 def draw(self): linearGradient = QLinearGradient(140, 280, 140, 310) linearGradient.setColorAt(0.2, QColor("#c40")) #10%處 linearGradient.setColorAt(1.0, QColor("#800400")) # # linearGradient.setColorAt(1.0, Qt.black) #100%處黑色 self.qp.setPen(QPen(Qt.black, 2)) #邊線 # self.qp.setBrush(linearGradient) #設置畫刷 self.qpp = QPainterPath() #路徑 self.qpp.moveTo(self.rect[0] + self.rect[2] - 40, self.rect[1] + self.rect[3] - 2) self.qpp.arcTo(self.rect[0] + self.rect[2] - 40, self.rect[1] - 2 , 30.0, 30.0, 270.0, 180.0) #(70, 30, R*2, R*2, 0, 180);(70,30)是起始位置,R是半徑,270是起始角度,180是要畫的角度 self.qpp.lineTo(self.rect[0], self.rect[1]-2) self.qpp.arcTo(self.rect[0]-15, self.rect[1] - 3, 60.0, 40.0, 90.0, 125.0) # self.qpp.arcTo(self.rect[0]-20, self.rect[1] + 26, 20.0, 20.0, 90.0, 30.0) self.qpp.closeSubpath() self.qp.drawPath(self.qpp) class hand(Shape): #手 def draw(self): self.qp.setBrush(self.color) #設置畫刷 self.qp.drawEllipse(self.rect) #畫圓形x,y,w,h 120, 25, 160, 160 class chest(Shape): #白色肚兜 def draw(self): self.color = Qt.white self.qp.setPen(QPen(Qt.black, 2)) #邊線 self.qp.setBrush(self.color) #設置畫刷 self.qpp = QPainterPath() #路徑 self.qpp.moveTo(self.rect[0] + 30 , self.rect[1] + 20) self.qpp.arcTo(self.rect[0] , self.rect[1] , 170.0, 170.0, 130.0, 280.0) #(70, 30, R*2, R*2, 0, 180);(70,30)是起始位置,R是半徑,270是起始角度,180是要畫的角度 self.qpp.closeSubpath() self.qp.drawPath(self.qpp) class half(Shape): #口袋 def draw(self): self.color = Qt.white self.qp.setPen(QPen(Qt.black, 2)) #邊線 self.qp.setBrush(self.color) #設置畫刷 self.qpp = QPainterPath() #路徑 self.qpp.moveTo(self.rect[0] , self.rect[1] + 10) self.qpp.arcTo(self.rect[0] , self.rect[1] - 55 , self.rect[2], self.rect[3], 180.0, 180.0) #(70, 30, R*2, R*2, 0, 180);(70,30)是起始位置,R是半徑,270是起始角度,180是要畫的角度 self.qpp.closeSubpath() self.qp.drawPath(self.qpp) class bellc(Shape): #鈴鐺中心 def draw(self): self.qp.setBrush(self.color) #設置畫刷 self.qp.drawEllipse(self.rect) #畫圓形x,y,w,h 120, 25, 160, 160 class bellv(Liner): #鈴鐺豎線 def draw(self): self.qp.drawLine(self.rect) class bellh(Liner): #橫線 # def __init__(self, qp, start_point, w, c=0): # self.qp = qp # # self.start_point = start_point #起始坐標 # self.w = w # self.c = c def draw(self): self.qp.drawLine(self.rect) class Bells: # 鈴鐺組合 def __init__(self, qp, start_point, w, h): # w,h是鈴鐺的寬、高 self.qp = qp # self.start_point = start_point #起始坐標 self.w = w self.h = h self.be = bell(self.qp, self.be_cacu(), QColor("#a9a100")) #鈴鐺 self.bec = bellc(self.qp, self.bec_cacu(),Qt.black) #鈴鐺中心 self.belv = bellv(self.qp, self.belv_cacu()) #鈴鐺豎線 self.belh1 = bellh(self.qp, self.belh1_cacu()) self.belh2 = bellh(self.qp, self.belh2_cacu()) def draw(self): self.be.draw() self.bec.draw() self.belv.draw() self.belh1.draw() self.belh2.draw() def belh1_cacu(self): # 計算鈴鐺橫線的坐標 x = self.start_point[0] + 2 y = self.start_point[1] -3 w = x + 36 h = y return QLineF(x, y, w, h) def belh2_cacu(self): # 計算鈴鐺橫線的坐標 x = self.start_point[0] y = self.start_point[1] + 2 w = x + 40 h = y return QLineF(x, y, w, h) def belv_cacu(self): # 計算鈴鐺豎線的坐標 x = self.start_point[0] + 20 y = self.start_point[1] + 20 w = x h = y + 8 return QLineF(x, y, w, h) def bec_cacu(self): # 計算鈴鐺的坐標(圓角矩形) x = self.start_point[0] + self.w /2 - 5 y = self.start_point[1] + 8 w = 10 h = 10 return QRect(x, y, w, h) def be_cacu(self): # 計算鈴鐺的坐標(圓角矩形) x = self.start_point[0] + self.w /2 - 20 y = self.start_point[1] - 12 w = 40 h = 40 return QRect(x, y, w, h) class Bodys: # 身體組合 def __init__(self, qp, start_point, w, h): # w,h是帽子的寬、高 self.qp = qp # self.start_point = start_point #起始坐標 self.w = w self.h = h self.bod = body(self.qp, self.bod_cacu()) #實例化身體 self.che = chest(self.qp, self.che_cacu()) #實例化白色肚兜 self.ha = half(self.qp, self.ha_cacu()) #實例化口袋 self.coll = collar(self.qp, self.col_cacu()) # 實例化項圈 self.hnd0 = hand(self.qp, self.hnd0_cacu(), Qt.white) #左手 self.hnd1 = hand(self.qp, self.hnd1_cacu(), Qt.white) #左手 self.ft1 = foot(self.qp, self.ft1_cacu(), Qt.white) #腳 self.ft2 = foot(self.qp, self.ft2_cacu(), Qt.white) #腳 self.bels = Bells(self.qp, (240, 300), 40, 40) def draw(self): # 繪制 self.bod.draw() #調用項圈方法繪制 self.che.draw() self.ha.draw() self.coll.draw() self.hnd0.draw() self.hnd1.draw() self.ft1.draw() self.ft2.draw() self.bels.draw() def ft1_cacu(self): # 計算腳的坐標 x1 = self.start_point[0] y1 = self.start_point[1] + 170 x2 = 120 y2 = 30 return (x1, y1, x2, y2) def ft2_cacu(self): # 計算腳的坐標(圓角矩形) x1 = self.start_point[0] + 130 y1 = self.start_point[1] + 170 x2 = 120 y2 = 30 return (x1, y1, x2, y2) def hnd0_cacu(self): # 計算手的坐標(圓角矩形) x = self.start_point[0] - 78 y = self.start_point[1] + 25 w = 60 h = 60 return QRect(x, y, w, h) def hnd1_cacu(self): # 計算手的坐標(圓角矩形) x = self.start_point[0] + self.h + 20 y = self.start_point[1] + 25 w = 60 h = 60 return QRect(x, y, w, h) def ha_cacu(self): # 計算口袋的坐標(圓角矩形) x = self.start_point[0] + 48 y = self.start_point[1] + 40 w = 130 h = 130 return (x, y, w, h) def che_cacu(self): # 計算白色肚兜的坐標(圓角矩形) x = self.start_point[0] + 28 y = self.start_point[1] - 30 w = 170 h = 170 return (x, y, w, h) def col_cacu(self): # 計算項圈的坐標(圓角矩形) x1 = self.start_point[0] y1 = self.start_point[1] - 20 x2 = 230 y2 = 20 return (x1, y1, x2, y2) def bod_cacu(self): # 計算身體的坐標 x = self.start_point[0] y = self.start_point[1] w = 230 h = 165 return (x, y, w, h) class Example(QWidget): def __init__(self, w, h): super().__init__() self.qp = QPainter() # 畫筆實例 self.rect = QRect() self.color = QColor() self.start_point = (100,30) #頭部的起始位置 self.w = w self.h = h self.initUI() self.heads = Heads(self.qp,self.start_point, 320, 300) # w,h self.bo = Bodys(self.qp, (145,300), 230, 230) #start_point,w,h def initUI(self): self.setGeometry(100, 300, self.w, self.h) # 窗口在屏幕上的坐標和大小:x,y,w,h self.setWindowTitle('叮當貓') self.show() # rect = QRect(120, 25, 160, 160) # self.hd = head(self.qp, self.rect, self.color) def paintEvent(self, e): self.qp.begin(self) self.drawBrushes(self.qp) #調用方法 self.qp.end() def drawBrushes(self, qp): self.heads.draw() self.bo.draw() # brush.setStyle(Qt.Dense1Pattern) #設置style # qp.setBrush(brush) #設置畫刷 # self.qp.drawEllipse(self.rect, self.color) #畫矩形x,y,w,h if __name__ == '__main__': app = QApplication(sys.argv) ex = Example(520, 760) #窗體大小 sys.exit(app.exec_())
到此這篇關於Python畫圖小案例之多啦A夢叮當貓超詳細註釋的文章就介紹到這瞭,更多相關Python 多啦A夢內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Python畫圖小案例之小雪人超詳細源碼註釋
- Python編程使用PyQt5庫實現動態水波進度條示例
- Python實現五子棋人機對戰 和人人對戰
- 基於Python實現五子棋-(人機對戰)
- QT利用QPainter繪制三維餅狀圖