Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML popup with blurred background?

QML popup with blurred background?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
9 Posts 3 Posters 13.8k 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.
  • I Offline
    I Offline
    igor_stravinsky
    wrote on last edited by
    #1

    I'd like to display a popup and have the background be a blurred version of the window the popup is appearing on top of (i.e. my main window)

    I'm assuming this process will involve using a FastBlur, and that I'll have to grabToImage to get the main screen's image to use as a source, but I'm not sure if I have to create an item to do the screen grab, or if there's some element I can simply ask for an image.

    Are there any examples of something like this using QML? It would seem like a fairly common request, given the sort of translucent UI tricks Android and iOS are introducing.

    raven-worxR 1 Reply Last reply
    0
    • I igor_stravinsky

      I'd like to display a popup and have the background be a blurred version of the window the popup is appearing on top of (i.e. my main window)

      I'm assuming this process will involve using a FastBlur, and that I'll have to grabToImage to get the main screen's image to use as a source, but I'm not sure if I have to create an item to do the screen grab, or if there's some element I can simply ask for an image.

      Are there any examples of something like this using QML? It would seem like a fairly common request, given the sort of translucent UI tricks Android and iOS are introducing.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @igor_stravinsky
      10s google search resulted in this

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      0
      • I Offline
        I Offline
        igor_stravinsky
        wrote on last edited by
        #3

        I've seen the solution for the blurred background using FastBlur.

        The difference is that that solution uses a png image that already exists as the blurred background. I could do the same thing, but I'd need a screenshot of the current UI to use for the FastBlur, and I haven't seen a QML solution for gathering a snapshot of the current window.

        timdayT 1 Reply Last reply
        0
        • I igor_stravinsky

          I've seen the solution for the blurred background using FastBlur.

          The difference is that that solution uses a png image that already exists as the blurred background. I could do the same thing, but I'd need a screenshot of the current UI to use for the FastBlur, and I haven't seen a QML solution for gathering a snapshot of the current window.

          timdayT Offline
          timdayT Offline
          timday
          wrote on last edited by timday
          #4

          @igor_stravinsky The FastBlur example uses an image, but FastBlur is just blurring whatever item its source property is pointing at. If you point it at your "main screen" (assuming that is itself a QML Item too) it'll blur that.

          If your dialog just overlaps part of the main screen, things probably get a bit more complex but you ought to be able to use ShaderEffectSource's sourceRect property to capture just the pixels needed for the blur (and in fact I see looking at raven-worx's SO link that's exactly what that does).

          (Alternative approach: In the past for doing some effects I have resorted to a C++ plugin to capture the whole QQuickView content and serve it up again via QQuickImageProvider to a QML Image for subsequent QML effects processing. That approach is a bit clunky and not as fast as you'd hope on mobile devices with high DPI displays. It's good enough for page transition effects; not so much for "live" effects... for those you really want to keep all the pixels in the OpenGL domain. Since then the purely QML world has got its own grabToImage... but so far as I can tell you can't currently do anything with the result other than save it to a file. Presumably you can close the loop by referring to that image file with some QML Image's source, but I can't imagine it being a viable approach for anything but actual screenshots and galleries of those screenshots: compressing a high DPI to png is not fast, no way it's going to be useful for "live" effects; at least the QQuickImageProvider approach never had to compress anything).

          I 1 Reply Last reply
          0
          • timdayT timday

            @igor_stravinsky The FastBlur example uses an image, but FastBlur is just blurring whatever item its source property is pointing at. If you point it at your "main screen" (assuming that is itself a QML Item too) it'll blur that.

            If your dialog just overlaps part of the main screen, things probably get a bit more complex but you ought to be able to use ShaderEffectSource's sourceRect property to capture just the pixels needed for the blur (and in fact I see looking at raven-worx's SO link that's exactly what that does).

            (Alternative approach: In the past for doing some effects I have resorted to a C++ plugin to capture the whole QQuickView content and serve it up again via QQuickImageProvider to a QML Image for subsequent QML effects processing. That approach is a bit clunky and not as fast as you'd hope on mobile devices with high DPI displays. It's good enough for page transition effects; not so much for "live" effects... for those you really want to keep all the pixels in the OpenGL domain. Since then the purely QML world has got its own grabToImage... but so far as I can tell you can't currently do anything with the result other than save it to a file. Presumably you can close the loop by referring to that image file with some QML Image's source, but I can't imagine it being a viable approach for anything but actual screenshots and galleries of those screenshots: compressing a high DPI to png is not fast, no way it's going to be useful for "live" effects; at least the QQuickImageProvider approach never had to compress anything).

            I Offline
            I Offline
            igor_stravinsky
            wrote on last edited by
            #5

            @timday Thanks for the suggestions.

            Unfortunately, my popup covers my "main screen", and although that's a QML item, capturing that image in another QML items looks less than trivial.

            What I'd really like to be able to do is to create a translucent rectangle the size of the screen, and have it act like a blurry lens above the main window UI. That would eliminate the need to take a screenshot and then manipulate it's pixels. I haven't seen any indication that that's possible, however.

            raven-worxR timdayT 2 Replies Last reply
            0
            • I igor_stravinsky

              @timday Thanks for the suggestions.

              Unfortunately, my popup covers my "main screen", and although that's a QML item, capturing that image in another QML items looks less than trivial.

              What I'd really like to be able to do is to create a translucent rectangle the size of the screen, and have it act like a blurry lens above the main window UI. That would eliminate the need to take a screenshot and then manipulate it's pixels. I haven't seen any indication that that's possible, however.

              raven-worxR Offline
              raven-worxR Offline
              raven-worx
              Moderators
              wrote on last edited by raven-worx
              #6

              @igor_stravinsky
              why don't you simply try the posted example?! All it would take you is 5 minutes... and you would see that it does what you want...

              import QtQuick 2.3
              import QtQuick.Window 2.2
              import QtGraphicalEffects 1.0
              
              Window {
                  id: window
                  visible: true
                  width: 600
                  height:600
              
                  Rectangle {
                      id: container
                      anchors.fill: parent
              
                      Image {
                          id: image
              
                          anchors.fill: parent
                          source: "url/to/image.png"
                      }
              
                      Rectangle {
                          width: 50
                          height: 50
                          x: 50
                          y: 50
                          color: "red"
                      }
                  }
                  ShaderEffectSource {
                      id: effectSource
              
                      sourceItem: container
                      anchors.fill: container
                      sourceRect: Qt.rect(x,y, width, height)
                  }
              
                  FastBlur{
                      id: blur
                      anchors.fill: effectSource
              
                      source: effectSource
                      radius: 100
                  }
              }
              

              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
              If you have a question please use the forum so others can benefit from the solution in the future

              1 Reply Last reply
              2
              • I igor_stravinsky

                @timday Thanks for the suggestions.

                Unfortunately, my popup covers my "main screen", and although that's a QML item, capturing that image in another QML items looks less than trivial.

                What I'd really like to be able to do is to create a translucent rectangle the size of the screen, and have it act like a blurry lens above the main window UI. That would eliminate the need to take a screenshot and then manipulate it's pixels. I haven't seen any indication that that's possible, however.

                timdayT Offline
                timdayT Offline
                timday
                wrote on last edited by
                #7

                @igor_stravinsky said in QML popup with blurred background?:

                Unfortunately, my popup covers my "main screen", and although that's a QML item, capturing that image in another QML items looks less than trivial.
                What I'd really like to be able to do is to create a translucent rectangle the size of the screen, and have it act like a blurry lens above the main window UI. That would eliminate the need to take a screenshot and then manipulate it's pixels. I haven't seen any indication that that's possible, however.

                Er, that's exactly what the example does. It'd be a different story if your "main screen" was the OS' desktop, but if it's a QML item just use ShaderEffectSource and FastBlur. Entirely possible!

                I 1 Reply Last reply
                0
                • timdayT timday

                  @igor_stravinsky said in QML popup with blurred background?:

                  Unfortunately, my popup covers my "main screen", and although that's a QML item, capturing that image in another QML items looks less than trivial.
                  What I'd really like to be able to do is to create a translucent rectangle the size of the screen, and have it act like a blurry lens above the main window UI. That would eliminate the need to take a screenshot and then manipulate it's pixels. I haven't seen any indication that that's possible, however.

                  Er, that's exactly what the example does. It'd be a different story if your "main screen" was the OS' desktop, but if it's a QML item just use ShaderEffectSource and FastBlur. Entirely possible!

                  I Offline
                  I Offline
                  igor_stravinsky
                  wrote on last edited by igor_stravinsky
                  #8

                  @timday
                  Thanks for the help, Tim!

                  I got the background blur working from the main screen.

                  I had to implement this by having the main view blur its contents, and then show the popup. I was trying to find a way to have the popup blur its parent, so I could encapsulate the popup behavior. Although I could get the popup to pull it's blur from the parent view, I couldn't get it to apply the blur to the parent. Is there a way to do that from within a separate popup qml file?

                  In my case the qml file that spawns the dialog is several layers inside of the item at the top level. Although I can reach up and find the correct parent to name as the sourceItem, I can't anchor to that item. When I try that, I get an error "QML ShaderEffectSource: Cannot anchor to an item that isn't a parent or sibling."

                  timdayT 1 Reply Last reply
                  0
                  • I igor_stravinsky

                    @timday
                    Thanks for the help, Tim!

                    I got the background blur working from the main screen.

                    I had to implement this by having the main view blur its contents, and then show the popup. I was trying to find a way to have the popup blur its parent, so I could encapsulate the popup behavior. Although I could get the popup to pull it's blur from the parent view, I couldn't get it to apply the blur to the parent. Is there a way to do that from within a separate popup qml file?

                    In my case the qml file that spawns the dialog is several layers inside of the item at the top level. Although I can reach up and find the correct parent to name as the sourceItem, I can't anchor to that item. When I try that, I get an error "QML ShaderEffectSource: Cannot anchor to an item that isn't a parent or sibling."

                    timdayT Offline
                    timdayT Offline
                    timday
                    wrote on last edited by timday
                    #9

                    @igor_stravinsky

                    Hmmm you got me playing around with this a bit myself... my code produces this:

                    blurry cat

                    Note the dimming of the non-popup area is something built into Popup; see its 'dim' and 'modal' properties.

                    Code (runs in qmlscene in Qt 5.9.1):

                    import QtQuick 2.3
                    import QtQuick.Window 2.2
                    import QtQuick.Controls 2.2
                    import QtQuick.Layouts 1.3
                    import QtGraphicalEffects 1.0
                    
                    ApplicationWindow {
                      id: window
                      width: 640
                      height: 480
                    
                      Rectangle {
                        id: main
                        anchors.fill: parent
                        
                        Image {
                          anchors.fill: parent
                          source: 'http://placeimg.com/640/480/animals'
                          fillMode: Image.PreserveAspectFit
                        }
                    
                        MouseArea {
                          anchors.fill: parent
                          onClicked: popup.visible=true
                        }
                      }
                    
                      Popup {
                        id: popup
                        x: 0.5*(main.width-width)
                        y: 0.5*(main.height-height)
                        width: 320
                        height: 240
                        modal: true
                        padding: 0.0
                        background: Item {
                          ShaderEffectSource {
                            id: effectSource
                            sourceItem: main
                            anchors.fill: parent
                            sourceRect: Qt.rect(popup.x,popup.y,popup.width,popup.height)
                          }
                          FastBlur{
                            id: blur
                            anchors.fill: effectSource
                            source: effectSource
                            radius: 32
                          }
                        }
                    
                        contentItem: ColumnLayout {
                          anchors.fill: parent
                          Label {
                            text: '<b>Blurry popup</b>'
                            Layout.alignment: Qt.AlignCenter
                          }
                          Button {
                            text: 'OK'
                            Layout.alignment: Qt.AlignCenter
                            onClicked: popup.visible=false
                          }
                        }
                      }
                    }
                    
                    

                    Not sure what you mean about having to blur the whole background; this doesn't.

                    The thing about the "Cannot anchor to an item that isn't a parent or sibling."... not uncommon to run into that for non-trivial layouts; sometimes I find you just have to "do the math" and provide some explicit expressions using various x, y, width & height properties of the various items involved.

                    1 Reply Last reply
                    3

                    • Login

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