[英]How to put a gif in gui using python PyQt5
这个程序是一个交通灯程序,但我想在窗口的正确空间放一个gif,当颜色为绿色时显示行走的人gif,当红色或黄色时显示停止gif,所以我试图使用我得到的QMovie混合结果仍然出现错误或gif不会出现在窗口你能帮帮我吗?
from itertools import cycle
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer,Qt,QPoint
from PyQt5.QtWidgets import QApplication,QMainWindow
from PyQt5.QtGui import QPainter,QColor,QMovie
class TrafficLight(QMainWindow):
def __init__(self,parent = None):
super(TrafficLight, self).__init__(parent)
self.setWindowTitle("TrafficLight ")
self.traffic_light_color1 = cycle(\[
QColor('red'),
QColor('gray'),
QColor('gray')
\])
self.traffic_light_color2 = cycle(\[
QColor('gray'),
QColor('yellow'),
QColor('gray')
\])
self.traffic_light_color3 = cycle(\[
QColor('gray'),
QColor('gray'),
QColor('green')
\])
self._current_color1 = next(self.traffic_light_color1)
self._current_color2 = next(self.traffic_light_color2)
self._current_color3 = next(self.traffic_light_color3)
timer = QTimer(self, timeout=self.change_color)
x = 0
if x == 0 :
self.movie1 = QMovie("Walking-man2[enter image description here][1].gif")
self.movie1.frameChanged.connect(self.repaint)
self.movie1.start()
timer.start(30*100)
x = 1
elif x == 1 :
self.movie1 = QMovie("tenor(1).gif")
self.movie1.frameChanged.connect(self.repaint)
self.movie1.start()
timer.start(10*100)
x = 2
elif x == 2:
self.movie1 = QMovie("tenor(1).gif")
self.movie1.frameChanged.connect(self.repaint)
self.movie1.start()
timer.start(40*100)
x = 0
self.resize(700, 510)
@QtCore.pyqtSlot()
def change_color(self):
self._current_color1 = next(self.traffic_light_color1)
self._current_color2 = next(self.traffic_light_color2)
self._current_color3 = next(self.traffic_light_color3)
self.update()
def paintEvent(self, event):
p1 = QPainter(self)
p1.setBrush(self._current_color1)
p1.setPen(Qt.black)
p1.drawEllipse(QPoint(125, 125), 50, 50)
p2 = QPainter(self)
p2.setBrush(self._current_color2)
p2.setPen(Qt.black)
p2.drawEllipse(QPoint(125, 250),50,50)
p3 = QPainter(self)
p3.setBrush(self._current_color3)
p3.setPen(Qt.black)
p3.drawEllipse(QPoint(125, 375),50,50)
currentFrame = self.movie1.currentPixmap()
frameRect = currentFrame.rect()
frameRect.moveCenter(self.rect().center())
if frameRect.intersects(event.rect()):
painter = QPainter(self)
painter.drawPixmap(frameRect.left(), frameRect.top(), currentFrame)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = TrafficLight()
w.show()
sys.exit(app.exec_())
可以使用有限状态机(FSM)实现将一个状态更改为另一个状态的逻辑,幸运的是Qt使用状态机框架实现它:
from functools import partial
from PyQt5 import QtCore, QtGui, QtWidgets
class LightWidget(QtWidgets.QWidget):
def __init__(self, color, parent=None):
super(LightWidget, self).__init__(parent)
self._state = False
self._color = color
self.setFixedSize(150, 150)
@QtCore.pyqtSlot()
def turnOn(self):
self._state = True
self.update()
@QtCore.pyqtSlot()
def turnOff(self):
self._state = False
self.update()
def paintEvent(self, event):
color = self._color if self._state else QtGui.QColor('gray')
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.setPen(QtCore.Qt.black)
painter.setBrush(color)
painter.drawEllipse(self.rect())
class TrafficLightWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(TrafficLightWidget, self).__init__(parent)
hlay = QtWidgets.QHBoxLayout(self)
container = QtWidgets.QWidget()
container.setStyleSheet('''background-color : black''')
vlay = QtWidgets.QVBoxLayout(container)
self.m_red = LightWidget(QtGui.QColor("red"))
self.m_yellow = LightWidget(QtGui.QColor("yellow"))
self.m_green = LightWidget(QtGui.QColor("green"))
vlay.addWidget(self.m_red)
vlay.addWidget(self.m_yellow)
vlay.addWidget(self.m_green)
hlay.addWidget(container, alignment=QtCore.Qt.AlignCenter)
self.label = QtWidgets.QLabel("Test", alignment=QtCore.Qt.AlignCenter)
hlay.addWidget(self.label, 1)
red_to_yellow = createLightState(self.m_red, 30*1000, partial(self.change_gif, "gif_red.gif"))
yellow_to_green = createLightState(self.m_yellow, 20*1000, partial(self.change_gif, "gif_yellow.gif"))
green_to_yellow = createLightState(self.m_green, 40*1000, partial(self.change_gif, "gif_green.gif"))
yellow_to_red = createLightState(self.m_yellow, 20*1000, partial(self.change_gif, "gif_yellow.gif"))
red_to_yellow.addTransition(red_to_yellow.finished, yellow_to_green)
yellow_to_green.addTransition(yellow_to_green.finished, green_to_yellow)
green_to_yellow.addTransition(green_to_yellow.finished, yellow_to_red)
yellow_to_red.addTransition(yellow_to_red.finished, red_to_yellow)
machine = QtCore.QStateMachine(self)
machine.addState(red_to_yellow)
machine.addState(yellow_to_green)
machine.addState(green_to_yellow)
machine.addState(yellow_to_red)
machine.setInitialState(red_to_yellow)
machine.start()
@QtCore.pyqtSlot()
def change_gif(self, gif):
last_movie = self.label.movie()
movie = QtGui.QMovie(gif)
self.label.setMovie(movie)
movie.start()
if last_movie is not None:
last_movie.deleteLater()
def createLightState(light, duration, callback):
lightState = QtCore.QState()
timer = QtCore.QTimer(
lightState,
interval=duration,
singleShot=True
)
timing = QtCore.QState(lightState)
timing.entered.connect(light.turnOn)
timing.entered.connect(callback)
timing.entered.connect(timer.start)
timing.exited.connect(light.turnOff)
done = QtCore.QFinalState(lightState)
timing.addTransition(timer.timeout, done)
lightState.setInitialState(timing)
return lightState
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = TrafficLightWidget()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
虽然答案并不像eyllanesc那样华丽......你可以让椭圆依赖于变量颜色,然后改变存储的变量颜色并调用update()。 可以使用标签显示gif
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QTimer,Qt,QPoint
from PyQt5.QtWidgets import QApplication,QMainWindow
from PyQt5.QtGui import QPainter,QColor,QMovie
class TrafficLight(QtWidgets.QWidget):
def __init__(self,parent = None):
super(TrafficLight, self).__init__(parent)
self.setWindowTitle("TrafficLight ")
layout = QtWidgets.QHBoxLayout()
self.setLayout(layout)
self.lblGif = QtWidgets.QLabel()
layout.addSpacing(300)
layout.addWidget(self.lblGif)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.changeLight)
self.timer.start(3000)
self.resize(700, 510)
self.x = 0
self.changeLight()
def changeLight(self):
if self.x == 0 :
self.color1 = QColor('red')
self.color2 = QColor('grey')
self.color3 = QColor('grey')
self.loadGif('wait.gif')
self.x = 1
elif self.x == 1 :
self.color1 = QColor('grey')
self.color2 = QColor('yellow')
self.color3 = QColor('grey')
self.loadGif('almost.gif')
self.x = 2
elif self.x == 2:
self.color1 = QColor('grey')
self.color2 = QColor('grey')
self.color3 = QColor('green')
self.loadGif('walk.gif')
self.x = 0
self.update()
def loadGif(self, path):
movie = QtGui.QMovie(path)
self.lblGif.setMovie(movie)
movie.start()
def paintEvent(self, event):
p1 = QPainter(self)
p1.setBrush(self.color1)
p1.setPen(Qt.black)
p1.drawEllipse(QPoint(125, 125), 50, 50)
p1.end()
p2 = QPainter(self)
p2.setBrush(self.color2)
p2.setPen(Qt.black)
p2.drawEllipse(QPoint(125, 250),50,50)
p2.end()
p3 = QPainter(self)
p3.setBrush(self.color3)
p3.setPen(Qt.black)
p3.drawEllipse(QPoint(125, 375),50,50)
p3.end()
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
w = TrafficLight()
w.show()
sys.exit(app.exec_())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.