Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to make animated backgrounds?
QtWS25 Last Chance

How to make animated backgrounds?

Scheduled Pinned Locked Moved Unsolved General and Desktop
24 Posts 6 Posters 2.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Bonnie
    21 Jul 2024, 22:28

    @Mizmas said in How to make animated backgrounds?:

    @artwaw I haven't tried it yet, but would it be possible to use a QStackedWidget, have the QLabel in one page, and the QFrame widget on another page. Could you then display both pages at the same time?

    This is also possible, but not in designer :)

    M Offline
    M Offline
    Mizmas
    wrote on 21 Jul 2024, 22:46 last edited by
    #11

    @Bonnie said in How to make animated backgrounds?:

    @artwaw I haven't tried it yet, but would it be possible to use a QStackedWidget, have the QLabel in one page, and the QFrame widget on another page. Could you then display both pages at the same time?

    This is also possible, but not in designer :)

    How? I've used QStackedWidget a couple of times only setting the pages with setCurrentIndex (index)

    B 1 Reply Last reply 21 Jul 2024, 23:26
    0
    • M Mizmas
      21 Jul 2024, 22:46

      @Bonnie said in How to make animated backgrounds?:

      @artwaw I haven't tried it yet, but would it be possible to use a QStackedWidget, have the QLabel in one page, and the QFrame widget on another page. Could you then display both pages at the same time?

      This is also possible, but not in designer :)

      How? I've used QStackedWidget a couple of times only setting the pages with setCurrentIndex (index)

      B Offline
      B Offline
      Bonnie
      wrote on 21 Jul 2024, 23:26 last edited by
      #12

      @Mizmas said in How to make animated backgrounds?:

      @Bonnie said in How to make animated backgrounds?:

      @artwaw I haven't tried it yet, but would it be possible to use a QStackedWidget, have the QLabel in one page, and the QFrame widget on another page. Could you then display both pages at the same time?

      This is also possible, but not in designer :)

      How? I've used QStackedWidget a couple of times only setting the pages with setCurrentIndex (index)

      QStackedWidget uses QStackedLayout class to manage child widgets.
      QStackedLayout can set stackingMode to QStackedLayout::StackAll to show all the widgets.
      So just need to get a QLayout * by calling the stackedWidget's layout() method and convert it to QStackedLayout *.

      M 1 Reply Last reply 24 Jul 2024, 15:37
      3
      • A Offline
        A Offline
        artwaw
        wrote on 22 Jul 2024, 13:09 last edited by
        #13

        @Bonnie thanks for the insight, I was not aware. FE is not the area where I play a lot :)
        I made notes, time to learn new things!

        For more information please re-read.

        Kind Regards,
        Artur

        1 Reply Last reply
        1
        • B Bonnie
          21 Jul 2024, 23:26

          @Mizmas said in How to make animated backgrounds?:

          @Bonnie said in How to make animated backgrounds?:

          @artwaw I haven't tried it yet, but would it be possible to use a QStackedWidget, have the QLabel in one page, and the QFrame widget on another page. Could you then display both pages at the same time?

          This is also possible, but not in designer :)

          How? I've used QStackedWidget a couple of times only setting the pages with setCurrentIndex (index)

          QStackedWidget uses QStackedLayout class to manage child widgets.
          QStackedLayout can set stackingMode to QStackedLayout::StackAll to show all the widgets.
          So just need to get a QLayout * by calling the stackedWidget's layout() method and convert it to QStackedLayout *.

          M Offline
          M Offline
          Mizmas
          wrote on 24 Jul 2024, 15:37 last edited by
          #14

          @Bonnie Thanks for all the tips, I've tried it with a random gif in a stacked widget and it works with your method.
          python_VpYj91G8im-ezgif.com-video-to-gif-converter (1).gif

          If anyone finds this thread in the future I did it like this:

                  self.your_stacked_widget = self.findChild(QStackedWidget, 'your_stacked_widget')
                  self.background_label = self.findChild(QLabel, 'background_label')
          
                  movie = QMovie(":/your_gif.gif")
                  movie.setScaledSize(self.your_stacked_widget.size())
                  self.background_label.setMovie(movie)
                  movie.start()
          
                  if self.your_stacked_widget:
                      # Get the QLayout from the stacked widget and cast it to QStackedLayout
                      self.stackedLayout = self.your_stacked_widget.layout()
          
                      if isinstance(self.stackedLayout, QStackedLayout):
                          # Set the stacking mode to StackAll to show all widgets
                          self.stackedLayout.setStackingMode(QStackedLayout.StackingMode.StackAll)
          

          Would this be most straightforward method if you want to lay everything out in QT Designer?

          P B 2 Replies Last reply 24 Jul 2024, 16:11
          4
          • M Mizmas
            24 Jul 2024, 15:37

            @Bonnie Thanks for all the tips, I've tried it with a random gif in a stacked widget and it works with your method.
            python_VpYj91G8im-ezgif.com-video-to-gif-converter (1).gif

            If anyone finds this thread in the future I did it like this:

                    self.your_stacked_widget = self.findChild(QStackedWidget, 'your_stacked_widget')
                    self.background_label = self.findChild(QLabel, 'background_label')
            
                    movie = QMovie(":/your_gif.gif")
                    movie.setScaledSize(self.your_stacked_widget.size())
                    self.background_label.setMovie(movie)
                    movie.start()
            
                    if self.your_stacked_widget:
                        # Get the QLayout from the stacked widget and cast it to QStackedLayout
                        self.stackedLayout = self.your_stacked_widget.layout()
            
                        if isinstance(self.stackedLayout, QStackedLayout):
                            # Set the stacking mode to StackAll to show all widgets
                            self.stackedLayout.setStackingMode(QStackedLayout.StackingMode.StackAll)
            

            Would this be most straightforward method if you want to lay everything out in QT Designer?

            P Offline
            P Offline
            Pl45m4
            wrote on 24 Jul 2024, 16:11 last edited by
            #15

            @Mizmas

            LOL that looks hilarious :D
            Didn't know that it was possible. Also thanks to @Bonnie


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            1 Reply Last reply
            0
            • M Mizmas
              24 Jul 2024, 15:37

              @Bonnie Thanks for all the tips, I've tried it with a random gif in a stacked widget and it works with your method.
              python_VpYj91G8im-ezgif.com-video-to-gif-converter (1).gif

              If anyone finds this thread in the future I did it like this:

                      self.your_stacked_widget = self.findChild(QStackedWidget, 'your_stacked_widget')
                      self.background_label = self.findChild(QLabel, 'background_label')
              
                      movie = QMovie(":/your_gif.gif")
                      movie.setScaledSize(self.your_stacked_widget.size())
                      self.background_label.setMovie(movie)
                      movie.start()
              
                      if self.your_stacked_widget:
                          # Get the QLayout from the stacked widget and cast it to QStackedLayout
                          self.stackedLayout = self.your_stacked_widget.layout()
              
                          if isinstance(self.stackedLayout, QStackedLayout):
                              # Set the stacking mode to StackAll to show all widgets
                              self.stackedLayout.setStackingMode(QStackedLayout.StackingMode.StackAll)
              

              Would this be most straightforward method if you want to lay everything out in QT Designer?

              B Offline
              B Offline
              Bonnie
              wrote on 25 Jul 2024, 01:51 last edited by Bonnie
              #16

              @Mizmas said in How to make animated backgrounds?:

              Would this be most straightforward method if you want to lay everything out in QT Designer?

              I have another approach, but I don't know how to do that in PyQt, so I'll just show it in C++.
              To make a widget in designer still acting like a QWidget/QFrame, but actually being a QLabel, we can use promoting.
              (In case anyone don't know about promoting widgets, here's the documentation: https://doc.qt.io/qt-6/designer-using-custom-widgets.html#promoting-widgets)
              So right click the background widget and select "Promote to ...".
              It would be great if we can promote it to QLabel directly, sadly designer doesn't allow that, so we promote it to a custom class name, say "QLabelWidget" with the header file "qlabelwidget.h".
              Then create "qlabelwidget.h" with below content:

              #ifndef QLABELWIDGET_H
              #define QLABELWIDGET_H
              #include <QLabel>
              typedef QLabel QLabelWidget;
              #endif // QLABELWIDGET_H
              

              So the background widget will become a QLabelWidget, aka QLabel. You cannot edit its QLabel properties in the designer, but it can call QLabel member functions in the code. Since QMovie can only be set in the code, I think that's not a problem.

              M 1 Reply Last reply 25 Jul 2024, 15:01
              3
              • B Bonnie
                25 Jul 2024, 01:51

                @Mizmas said in How to make animated backgrounds?:

                Would this be most straightforward method if you want to lay everything out in QT Designer?

                I have another approach, but I don't know how to do that in PyQt, so I'll just show it in C++.
                To make a widget in designer still acting like a QWidget/QFrame, but actually being a QLabel, we can use promoting.
                (In case anyone don't know about promoting widgets, here's the documentation: https://doc.qt.io/qt-6/designer-using-custom-widgets.html#promoting-widgets)
                So right click the background widget and select "Promote to ...".
                It would be great if we can promote it to QLabel directly, sadly designer doesn't allow that, so we promote it to a custom class name, say "QLabelWidget" with the header file "qlabelwidget.h".
                Then create "qlabelwidget.h" with below content:

                #ifndef QLABELWIDGET_H
                #define QLABELWIDGET_H
                #include <QLabel>
                typedef QLabel QLabelWidget;
                #endif // QLABELWIDGET_H
                

                So the background widget will become a QLabelWidget, aka QLabel. You cannot edit its QLabel properties in the designer, but it can call QLabel member functions in the code. Since QMovie can only be set in the code, I think that's not a problem.

                M Offline
                M Offline
                Mizmas
                wrote on 25 Jul 2024, 15:01 last edited by
                #17

                @Bonnie Yes, that's definitely more straight forward, thanks again :D

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  Mizmas
                  wrote on 27 Jul 2024, 21:30 last edited by
                  #18

                  I've been experimenting some more with gif backgrounds, subclassing a QFrame using QLabel.
                  I tried making a background for a push button, and the background gif changes based whether the cursor is hovering over the button or not.
                  This is what I have so far: https://streamable.com/k02xqk

                  # set initial state for website button
                      self.website_button_frame = self.findChild(GifFrame, 'website_button_frame')
                      self.gif = QMovie(':/animations/website_logo.gif')
                      self.gif.setScaledSize(self.website_button_frame.size())
                      self.website_button_frame.setMovie(self.gif)
                      self.gif.start()
                      
                      # Install an event filter on the website button
                      self.website_button.installEventFilter(self)
                  
                  # website_button hover/not hover filter
                  def eventFilter(self, watched, event):
                      if watched == self.website_button:
                          if event.type() == QEvent.Type.Enter:
                              # Action when hovering
                              gif = QMovie(":/animations/website_logo_purple.gif")
                              gif.setScaledSize(self.website_button_frame.size())
                              self.website_button_frame.setMovie(gif)
                              gif.start()
                          elif event.type() == QEvent.Type.Leave:
                              # Action when not hovering
                              gif = QMovie(":/animations/website_logo.gif")
                              gif.setScaledSize(self.website_button_frame.size())
                              self.website_button_frame.setMovie(gif)
                              gif.start()
                      return super().eventFilter(watched, event)
                  

                  Basically, I'm using two gifs with two different colors, they both have transparent backgrounds and solid color objects. I'm using an event filter to change the two, based on whether the cursor is hovering over the button or not. The problem is that this transition is not smooth and jittery. This is because both the QMovie objects start over again from the start and not on the frame that was displayed before. I've tried using methods of the QMovie like currentFrameNumber() and jumpToFrame(), but they only seem to work if you're using the same QMovie (at least I couldn't get it to work).

                  Is there some approach I can take to work with a single .gif file, and somehow programmatically change the color of the solid color objects while the gif is playing? Or is there some different stuff I can try, maybe outside of QT?

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    GrecKo
                    Qt Champions 2018
                    wrote on 27 Jul 2024, 22:40 last edited by GrecKo
                    #19

                    There is some different stuff you can try, inside Qt. Namely Qt Quick.
                    In my opinion it is much more suited to the kind of application you appear to make.
                    QtQuick.Effects's MultiEffect can color any abritrary item

                    For fun I tried to recreate the stuff you showed in QML with Qt Quick, here's the quick and a bit ugly code:

                    import QtQuick
                    import QtQuick.Controls
                    import QtQuick.Effects
                    
                    ApplicationWindow {
                        id: window
                        width: 640
                        height: 480
                        visible: true
                    
                        property real radius: 8
                    
                        flags: Qt.FramelessWindowHint
                        color: "transparent"
                    
                        Rectangle {
                            parent: window.contentItem.parent
                            z: -1
                            anchors.fill: parent
                            color: "#F7BF8A"
                            radius: window.radius
                            border.width: 1
                        }
                        footer: Rectangle {
                            color: "#B1C368"
                            height: 50
                            topLeftRadius: 0
                            topRightRadius: 0
                            bottomLeftRadius: window.radius
                            bottomRightRadius: window.radius
                            border.width: 1
                            Text {
                                id: siteLink
                                anchors {
                                    verticalCenter: parent.verticalCenter
                                    right: parent.right
                                    rightMargin: 20
                                }
                                text: "By midimagic"
                                font.family: "Courier New"
                                color: hoverHandler.hovered ? "#8D7BDE" : "black"
                    
                                HoverHandler {
                                    id: hoverHandler
                                    cursorShape: Qt.PointingHandCursor
                                }
                                TapHandler {
                                    onTapped: Qt.openUrlExternally("https://forum.qt.io")
                                }
                                AnimatedImage {
                                    id: siteGif
                                    visible: false
                                    anchors {
                                        fill: parent
                                        margins: -15
                                    }
                                    source: "https://emoji.discadia.com/emojis/d3897e57-3a33-4136-a6bb-882343233261.gif"
                                    fillMode: Image.PreserveAspectFit
                                }
                                MultiEffect {
                                    anchors.fill: siteGif
                                    source: siteGif
                                    colorizationColor: siteLink.color
                                    colorization: 1
                                }
                            }
                        }
                    }
                    

                    Here's the result: ( the sluggyness is only in the recording, it runs smooth)
                    colored background gif

                    M 1 Reply Last reply 27 Jul 2024, 23:35
                    0
                    • G GrecKo
                      27 Jul 2024, 22:40

                      There is some different stuff you can try, inside Qt. Namely Qt Quick.
                      In my opinion it is much more suited to the kind of application you appear to make.
                      QtQuick.Effects's MultiEffect can color any abritrary item

                      For fun I tried to recreate the stuff you showed in QML with Qt Quick, here's the quick and a bit ugly code:

                      import QtQuick
                      import QtQuick.Controls
                      import QtQuick.Effects
                      
                      ApplicationWindow {
                          id: window
                          width: 640
                          height: 480
                          visible: true
                      
                          property real radius: 8
                      
                          flags: Qt.FramelessWindowHint
                          color: "transparent"
                      
                          Rectangle {
                              parent: window.contentItem.parent
                              z: -1
                              anchors.fill: parent
                              color: "#F7BF8A"
                              radius: window.radius
                              border.width: 1
                          }
                          footer: Rectangle {
                              color: "#B1C368"
                              height: 50
                              topLeftRadius: 0
                              topRightRadius: 0
                              bottomLeftRadius: window.radius
                              bottomRightRadius: window.radius
                              border.width: 1
                              Text {
                                  id: siteLink
                                  anchors {
                                      verticalCenter: parent.verticalCenter
                                      right: parent.right
                                      rightMargin: 20
                                  }
                                  text: "By midimagic"
                                  font.family: "Courier New"
                                  color: hoverHandler.hovered ? "#8D7BDE" : "black"
                      
                                  HoverHandler {
                                      id: hoverHandler
                                      cursorShape: Qt.PointingHandCursor
                                  }
                                  TapHandler {
                                      onTapped: Qt.openUrlExternally("https://forum.qt.io")
                                  }
                                  AnimatedImage {
                                      id: siteGif
                                      visible: false
                                      anchors {
                                          fill: parent
                                          margins: -15
                                      }
                                      source: "https://emoji.discadia.com/emojis/d3897e57-3a33-4136-a6bb-882343233261.gif"
                                      fillMode: Image.PreserveAspectFit
                                  }
                                  MultiEffect {
                                      anchors.fill: siteGif
                                      source: siteGif
                                      colorizationColor: siteLink.color
                                      colorization: 1
                                  }
                              }
                          }
                      }
                      

                      Here's the result: ( the sluggyness is only in the recording, it runs smooth)
                      colored background gif

                      M Offline
                      M Offline
                      Mizmas
                      wrote on 27 Jul 2024, 23:35 last edited by Mizmas
                      #20

                      @GrecKo Damn :D I've never used QT Quick before, but thank you so much

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        GrecKo
                        Qt Champions 2018
                        wrote on 27 Jul 2024, 23:40 last edited by
                        #21

                        Alternatively if you want to stick with QWidgets you could retrieve the current frame number of the running QMovie and set it to the new one when switching. With currentFrameNumber and jumpToFrame.

                        M 2 Replies Last reply 28 Jul 2024, 00:04
                        0
                        • G GrecKo
                          27 Jul 2024, 23:40

                          Alternatively if you want to stick with QWidgets you could retrieve the current frame number of the running QMovie and set it to the new one when switching. With currentFrameNumber and jumpToFrame.

                          M Offline
                          M Offline
                          Mizmas
                          wrote on 28 Jul 2024, 00:04 last edited by
                          #22

                          @GrecKo Yeah I've tried again using currentFrameNumber() and jumpToFrame() and it seems to work, I must've messed something up before. Thanks again

                          1 Reply Last reply
                          0
                          • G GrecKo
                            27 Jul 2024, 23:40

                            Alternatively if you want to stick with QWidgets you could retrieve the current frame number of the running QMovie and set it to the new one when switching. With currentFrameNumber and jumpToFrame.

                            M Offline
                            M Offline
                            Mizmas
                            wrote on 28 Jul 2024, 00:15 last edited by
                            #23

                            @GrecKo Though, there are times where the gifs begin to lag and slow down for a moment, even when the cursor is not interacting with them. This happens on all other QMovie objects with gifs that I've tried, even if there's no cursor interaction coded

                            A 1 Reply Last reply 29 Jul 2024, 09:12
                            0
                            • M Mizmas
                              28 Jul 2024, 00:15

                              @GrecKo Though, there are times where the gifs begin to lag and slow down for a moment, even when the cursor is not interacting with them. This happens on all other QMovie objects with gifs that I've tried, even if there's no cursor interaction coded

                              A Offline
                              A Offline
                              artwaw
                              wrote on 29 Jul 2024, 09:12 last edited by
                              #24

                              @Mizmas please check the release version of your program, the debug ones can be laggy for obvious reasons.

                              For more information please re-read.

                              Kind Regards,
                              Artur

                              1 Reply Last reply
                              0

                              20/24

                              27 Jul 2024, 23:35

                              • Login

                              • Login or register to search.
                              20 out of 24
                              • First post
                                20/24
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved