【问题标题】:How to put a gif in gui using python PyQt5如何使用 python PyQt5 在 gui 中放置 gif
【发布时间】:2019-03-11 14:57:44
【问题描述】:

这个程序是一个交通信号灯程序,但我想在窗口的右侧空间放置一个 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_())

【问题讨论】:

  • 重复:您应该编辑您之前在此处提出的问题:Is there a way to put a GIF into a Gui in python using pyqt5?
  • 我删除了它,因为我的问题含糊不清,对此我很抱歉。
  • @JansenLloydMacabangun .gif 应该在 GUI 的哪个部分?
  • 在窗口的右侧可能是那里的空白区域。
  • @JansenLloydMacabangun 你可以展示一个方案来更好地理解你,我还建议使用@username 来通知我你的消息

标签: python pyqt5


【解决方案1】:

将一种状态更改为另一种状态的逻辑可以使用有限状态机 (FSM) 来实现,幸运的是 Qt 使用The State Machine Framework 来实现它:

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_())

【讨论】:

    【解决方案2】:

    虽然答案没有 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_())
    

    【讨论】:

      猜你喜欢
      • 2022-06-12
      • 2018-06-22
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-15
      • 2016-01-27
      相关资源
      最近更新 更多