亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

python3+PyQt5 動畫和復雜形狀--實現千足蛇動畫程序

2019-11-06 06:52:25
字體:
來源:轉載
供稿:網友

本文通過Python3+PyQt5實現《python Qt Gui 快速編程》這本書的千足蛇動畫程序,采用QGraphicsView,QGraphiCSScene,QGraphicsItem,這個程序包含有多個文本,圖片和框的頁面。有些圖形類在PyQt5已過時,所以本代碼改動幅度比較大。本文實現復雜形狀動畫內容,一種通過項自身定時器,另一種采用窗口超時處理程序來實現項目移動碰撞等功能。

1,通過自身定時器實現,完整代碼如下:

#!/usr/bin/env python3import mathimport randomimport sysfrom PyQt5.QtCore import (QTimer, QPointF, QRectF, Qt)from PyQt5.QtWidgets import (Qapplication, QDialog, QGraphicsItem, QGraphicsScene, QGraphicsView, QHBoxLayout, QPushButton, QSlider,QVBoxLayout)from PyQt5.QtGui import (QBrush, QColor,QPainter,QPainterPath,QPolygonF)SCENESIZE = 500INTERVAL = 1class Head(QGraphicsItem): Rect = QRectF(-30, -20, 60, 40) def __init__(self, color, angle, position): super(Head, self).__init__() self.color = color self.angle = angle self.setPos(position) def boundingRect(self): return Head.Rect def shape(self): path = QPainterPath() path.addEllipse(Head.Rect) return path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) painter.drawEllipse(Head.Rect) if option.levelOfDetailFromTransform(self.transform()) > 0.5: # Outer eyes painter.setBrush(QBrush(Qt.yellow)) painter.drawEllipse(-12, -19, 8, 8) painter.drawEllipse(-12, 11, 8, 8) if option.levelOfDetailFromTransform(self.transform())> 0.8: # Inner eyes painter.setBrush(QBrush(Qt.darkBlue)) painter.drawEllipse(-12, -19, 4, 4) painter.drawEllipse(-12, 11, 4, 4) if option.levelOfDetailFromTransform(self.transform()) > 0.9: # Nostrils painter.setBrush(QBrush(Qt.white)) painter.drawEllipse(-27, -5, 2, 2) painter.drawEllipse(-27, 3, 2, 2) def advance(self, phase): if phase == 0: angle = self.angle while True: flipper = 1 angle += random.random() * random.choice((-1, 1)) offset = flipper * random.random() x = self.x() + (offset * math.sin(math.radians(angle))) y = self.y() + (offset * math.cos(math.radians(angle))) if 0 <= x <= SCENESIZE and 0 <= y <= SCENESIZE: break else: flipper = -1 if flipper == 1 else 1 self.angle = angle self.position = QPointF(x, y) else: self.setRotation(random.random() * random.choice((-1, 1))) self.setPos(self.position) if self.scene(): for item in self.scene().collidingItems(self): if isinstance(item, Head): self.color.setRed(min(255, self.color.red() + 1)) else: item.color.setBlue(min(255, item.color.blue() + 1))class Segment(QGraphicsItem): def __init__(self, color, offset, parent): super(Segment, self).__init__(parent) self.color = color self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) x = offset + 15 y = -20 self.path.addPolygon(QPolygonF([QPointF(x, y), QPointF(x - 5, y - 12), QPointF(x - 5, y)])) self.path.closeSubpath() y = 20 self.path.addPolygon(QPolygonF([QPointF(x, y), QPointF(x - 5, y + 12), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) if option.levelOfDetailFromTransform(self.transform()) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def advance(self, phase): if phase == 0: matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change * random.random() if self.angle > 4.5: self.change = -1 self.angle -= 0.00001 elif self.angle < -4.5: self.change = 1 self.angle += 0.00001 elif phase == 1: self.setRotation(self.angle)class MainForm(QDialog): def __init__(self, parent=None): super(MainForm, self).__init__(parent) self.running = False self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, SCENESIZE, SCENESIZE) self.scene.setItemIndexMethod(QGraphicsScene.NoIndex) self.view = QGraphicsView() self.view.setRenderHint(QPainter.Antialiasing) self.view.setScene(self.scene) self.view.setFocusPolicy(Qt.NoFocus) zoomSlider = QSlider(Qt.Horizontal) zoomSlider.setRange(5, 200) zoomSlider.setValue(100) self.pauseButton = QPushButton("Pa&use") quitButton = QPushButton("&Quit") quitButton.setFocusPolicy(Qt.NoFocus) layout = QVBoxLayout() layout.addWidget(self.view) bottomLayout = QHBoxLayout() bottomLayout.addWidget(self.pauseButton) bottomLayout.addWidget(zoomSlider) bottomLayout.addWidget(quitButton) layout.addLayout(bottomLayout) self.setLayout(layout) zoomSlider.valueChanged[int].connect(self.zoom) quitButton.clicked.connect(self.accept) self.populate() self.startTimer(INTERVAL) self.setWindowTitle("Multipedes") def zoom(self, value): factor = value / 100.0 matrix=self.view.transform() matrix.reset() matrix.scale(factor, factor) self.view.setTransform(matrix) def pauSEOrResume(self): self.running = not self.running self.pauseButton.setText("Pa&use" if self.running else "Res&ume") def populate(self): red, green, blue = 0, 150, 0 for i in range(random.randint(6, 10)): angle = random.randint(0, 360) offset = random.randint(0, SCENESIZE // 2) half = SCENESIZE / 2 x = half + (offset * math.sin(math.radians(angle))) y = half + (offset * math.cos(math.radians(angle))) color = QColor(red, green, blue) head = Head(color, angle, QPointF(x, y)) color = QColor(red, green + random.randint(10, 60), blue) offset = 25 segment = Segment(color, offset, head) for j in range(random.randint(3, 7)): offset += 25 segment = Segment(color, offset, segment) head.setRotation(random.randint(0, 360)) self.scene.addItem(head) self.running = True def timerEvent(self, event): if not self.running: return dead = set() items = self.scene.items() if len(items) == 0: self.populate() return heads = set() for item in items: if isinstance(item, Head): heads.add(item) if item.color.red() == 255 and random.random() > 0.75: dead.add(item) if len(heads) == 1: dead = heads del heads while dead: item = dead.pop() self.scene.removeItem(item) del item self.scene.advance()app = QApplication(sys.argv)form = MainForm()rect = QApplication.desktop().availableGeometry()form.resize(int(rect.width() * 0.75), int(rect.height() * 0.9))form.show()app.exec_()

2,通過窗口超時處理程序實現,完整代碼如下:

#!/usr/bin/env python3import mathimport randomimport sysfrom PyQt5.QtCore import (QTimer, QPointF, QRectF, Qt)from PyQt5.QtWidgets import (QApplication, QDialog, QGraphicsItem, QGraphicsScene, QGraphicsView, QHBoxLayout, QPushButton, QSlider,QVBoxLayout)from PyQt5.QtGui import (QBrush, QColor,QPainter,QPainterPath,QPolygonF)SCENESIZE = 500INTERVAL = 1Running = Falseclass Head(QGraphicsItem): Rect = QRectF(-30, -20, 60, 40) def __init__(self, color, angle, position): super(Head, self).__init__() self.color = color self.angle = angle self.setPos(position) self.timer = QTimer() self.timer.timeout.connect(self.timeout) self.timer.start(INTERVAL) def boundingRect(self): return Head.Rect def shape(self): path = QPainterPath() path.addEllipse(Head.Rect) return path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) painter.drawEllipse(Head.Rect) if option.levelOfDetailFromTransform(self.transform()) > 0.5: # Outer eyes painter.setBrush(QBrush(Qt.yellow)) painter.drawEllipse(-12, -19, 8, 8) painter.drawEllipse(-12, 11, 8, 8) if option.levelOfDetailFromTransform(self.transform()) > 0.8: # Inner eyes painter.setBrush(QBrush(Qt.darkBlue)) painter.drawEllipse(-12, -19, 4, 4) painter.drawEllipse(-12, 11, 4, 4) if option.levelOfDetailFromTransform(self.transform()) > 0.9: # Nostrils painter.setBrush(QBrush(Qt.white)) painter.drawEllipse(-27, -5, 2, 2) painter.drawEllipse(-27, 3, 2, 2) def timeout(self): if not Running: return angle = self.angle while True: flipper = 1 angle += random.random() * random.choice((-1, 1)) offset = flipper * random.random() x = self.x() + (offset * math.sin(math.radians(angle))) y = self.y() + (offset * math.cos(math.radians(angle))) if 0 <= x <= SCENESIZE and 0 <= y <= SCENESIZE: break else: flipper = -1 if flipper == 1 else 1 self.angle = angle self.setRotation(random.random() * random.choice((-1, 1))) self.setPos(QPointF(x, y)) if self.scene(): for item in self.scene().collidingItems(self): if isinstance(item, Head): self.color.setRed(min(255, self.color.red() + 1)) else: item.color.setBlue(min(255, item.color.blue() + 1))class Segment(QGraphicsItem): def __init__(self, color, offset, parent): super(Segment, self).__init__(parent) self.color = color self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) x = offset + 15 y = -20 self.path.addPolygon(QPolygonF([QPointF(x, y), QPointF(x - 5, y - 12), QPointF(x - 5, y)])) self.path.closeSubpath() y = 20 self.path.addPolygon(QPolygonF([QPointF(x, y), QPointF(x - 5, y + 12), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 self.timer = QTimer() self.timer.timeout.connect(self.timeout) self.timer.start(INTERVAL) def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) if option.levelOfDetailFromTransform(self.transform()) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def timeout(self): if not Running: return matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change * random.random() if self.angle > 4.5: self.change = -1 self.angle -= 0.00001 elif self.angle < -4.5: self.change = 1 self.angle += 0.00001 self.setRotation(self.angle)class MainForm(QDialog): def __init__(self, parent=None): super(MainForm, self).__init__(parent) self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, SCENESIZE, SCENESIZE) self.scene.setItemIndexMethod(QGraphicsScene.NoIndex) self.view = QGraphicsView() self.view.setRenderHint(QPainter.Antialiasing) self.view.setScene(self.scene) self.view.setFocusPolicy(Qt.NoFocus) zoomSlider = QSlider(Qt.Horizontal) zoomSlider.setRange(5, 200) zoomSlider.setValue(100) self.pauseButton = QPushButton("Pa&use") quitButton = QPushButton("&Quit") quitButton.setFocusPolicy(Qt.NoFocus) layout = QVBoxLayout() layout.addWidget(self.view) bottomLayout = QHBoxLayout() bottomLayout.addWidget(self.pauseButton) bottomLayout.addWidget(zoomSlider) bottomLayout.addWidget(quitButton) layout.addLayout(bottomLayout) self.setLayout(layout) zoomSlider.valueChanged[int].connect(self.zoom) self.pauseButton.clicked.connect(self.pauseOrResume) quitButton.clicked.connect(self.accept) self.populate() self.startTimer(INTERVAL) self.setWindowTitle("Multipedes") def zoom(self, value): factor = value / 100.0 matrix=self.view.transform() matrix.reset() matrix.scale(factor, factor) self.view.setTransform(matrix) def pauseOrResume(self): global Running Running = not Running self.pauseButton.setText("Pa&use" if Running else "Res&ume") def populate(self): red, green, blue = 0, 150, 0 for i in range(random.randint(6, 10)): angle = random.randint(0, 360) offset = random.randint(0, SCENESIZE // 2) half = SCENESIZE / 2 x = half + (offset * math.sin(math.radians(angle))) y = half + (offset * math.cos(math.radians(angle))) color = QColor(red, green, blue) head = Head(color, angle, QPointF(x, y)) color = QColor(red, green + random.randint(10, 60), blue) offset = 25 segment = Segment(color, offset, head) for j in range(random.randint(3, 7)): offset += 25 segment = Segment(color, offset, segment) head.setRotation(random.randint(0, 360)) self.scene.addItem(head) global Running Running = True def timerEvent(self, event): if not Running: return dead = set() items = self.scene.items() if len(items) == 0: self.populate() return heads = set() for item in items: if isinstance(item, Head): heads.add(item) if item.color.red() == 255 and random.random() > 0.75: dead.add(item) if len(heads) == 1: dead = heads del heads while dead: item = dead.pop() self.scene.removeItem(item) del itemapp = QApplication(sys.argv)form = MainForm()rect = QApplication.desktop().availableGeometry()form.resize(int(rect.width() * 0.75), int(rect.height() * 0.9))form.show()app.exec_()

運行結果 這里寫圖片描述


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久婷婷天堂| 中文在线不卡视频| 亚洲电影免费观看高清完整版| 日本一欧美一欧美一亚洲视频| 国产成人精彩在线视频九色| 神马久久久久久| 国产精品一区二区三区毛片淫片| 日韩毛片中文字幕| 成人精品网站在线观看| 国产精品成人国产乱一区| 欧美日韩一二三四五区| 国产精品久久久久久久久免费看| 亚洲另类xxxx| 91精品免费久久久久久久久| 午夜免费在线观看精品视频| 一区二区三区精品99久久| 亚洲美女免费精品视频在线观看| 午夜精品美女自拍福到在线| 亚洲第一精品电影| 欧美黄网免费在线观看| 亚洲2020天天堂在线观看| 久久久久久一区二区三区| 日韩视频在线免费| 国产亚洲精品综合一区91| 久久伊人精品天天| 国内精品视频一区| 国产精品久久久久久久久久免费| 久热精品在线视频| 久久久久国产精品一区| 中文一区二区视频| 国产精品久久综合av爱欲tv| 国产精品大片wwwwww| 久久亚洲欧美日韩精品专区| 91精品国产电影| 久久男人av资源网站| 日韩人体视频一二区| 亚洲一区二区在线播放| 久久精品国产一区二区电影| 国产精品一香蕉国产线看观看| 91精品国产99久久久久久| 日韩在线视频网站| 久久久久久久国产精品视频| 国产女同一区二区| 青草青草久热精品视频在线网站| 精品国产乱码久久久久久天美| 久久久久久网址| 日韩精品中文字幕在线播放| 欧美—级a级欧美特级ar全黄| 色天天综合狠狠色| 97精品一区二区视频在线观看| 日韩av资源在线播放| 国产欧美亚洲精品| 性金发美女69hd大尺寸| 清纯唯美日韩制服另类| 国产精品久久久亚洲| 亚洲а∨天堂久久精品9966| 久久人人看视频| y97精品国产97久久久久久| 亚洲福利视频网站| 色偷偷av一区二区三区| 亚洲欧美精品在线| 日韩中文字幕在线免费观看| 亚洲丝袜在线视频| 欧美午夜精品久久久久久久| 96pao国产成视频永久免费| 久久久中精品2020中文| 福利微拍一区二区| 永久免费毛片在线播放不卡| 欧美性猛交视频| 国产精品一区二区三区免费视频| 国产精品一区二区在线| 国产精品一香蕉国产线看观看| 777精品视频| 日韩在线播放av| 另类图片亚洲另类| 午夜美女久久久久爽久久| 欧美在线视频播放| 超碰精品一区二区三区乱码| 欧美激情视频三区| 成人午夜小视频| 成人欧美在线观看| 亚洲国产私拍精品国模在线观看| 久久免费视频在线| 亚洲电影成人av99爱色| 午夜精品一区二区三区在线| 国产日韩亚洲欧美| 国产精品久久久久久久app| 久久久久久久一区二区三区| 精品国产拍在线观看| 亚洲理论在线a中文字幕| 一区二区欧美激情| 亚洲国产天堂久久国产91| 日韩国产精品亚洲а∨天堂免| 日韩欧美a级成人黄色| 26uuu国产精品视频| 国产欧美精品在线| 在线精品播放av| 久久激情五月丁香伊人| 亚洲精品一区二区三区不| 久久精品一偷一偷国产| 日韩中文在线视频| 81精品国产乱码久久久久久| 欧美日韩精品在线| 国精产品一区一区三区有限在线| 成人写真视频福利网| 国产精品影片在线观看| 精品久久久久久中文字幕| 91久久久久久久久久| 亚洲视频日韩精品| 欧美日韩国产一区二区三区| 国产精品爽黄69天堂a| 欧美成人免费全部| 伊人久久男人天堂| 少妇久久久久久| 91久久久久久| 最近2019免费中文字幕视频三| 日韩精品视频三区| 国产成人91久久精品| 中文字幕亚洲自拍| 欧美激情欧美狂野欧美精品| 性金发美女69hd大尺寸| 中文字幕久久久av一区| 91色琪琪电影亚洲精品久久| 91免费视频网站| 国产成人精品久久二区二区| 亚洲欧美色婷婷| 亚洲精品不卡在线| 国产成人a亚洲精品| 欧美日韩国产在线播放| 精品国产一区二区三区久久久| 亚洲成人久久电影| 国产免费亚洲高清| 欧美性xxxxxxxxx| 亚洲精品久久久久国产| 亚洲欧洲免费视频| 亚洲精品久久久久久久久久久| 国产成人aa精品一区在线播放| 91夜夜未满十八勿入爽爽影院| 欧美做受高潮1| 日韩在线中文视频| 精品久久久久久久久久久久久久| 91色中文字幕| 日韩欧美成人区| 欧美综合在线第二页| 日韩欧美一区二区三区| 国产狼人综合免费视频| 97在线视频观看| 久久视频免费在线播放| 色视频www在线播放国产成人| 中文字幕亚洲第一| 日韩专区中文字幕| www国产亚洲精品久久网站| 亚洲缚视频在线观看| 日韩视频免费在线| 91av国产在线| 国产精品aaaa| 亚洲美女久久久| 亚洲精品一区二区三区不| 国产精品都在这里| 欧美一级大胆视频| 国产成人精品一区二区在线| 日韩经典第一页| 久久久亚洲福利精品午夜| 97精品视频在线播放|