2017-06-09 74 views
0

我有一個帶有背景圖像的SwipeView。它有兩頁,兩頁都有一組控件和文本,我在它們下面放置了一個類似iOS的模糊圓角矩形,以便讀取更容易,但不會完全遮擋好背景。Qt QML帶有背景的SwipeView,如何在頁面移動時模糊右側區域?

I發現這個片段在這個線程,導致我用一個白色矩形與採樣的背景半透明狀FastBlur結合的末尾:https://forum.qt.io/topic/38297/a-semi-transparent-rectangle-that-also-blurs/7

Rectangle { 
    anchors.fill: fastBlur 
    color: "white" 
} 

FastBlur { 
    id: fastBlur 

    height: 124 

    width: parent.width 
    radius: 40 
    opacity: 0.55 

    source: ShaderEffectSource { 
     sourceItem: flickable 
     sourceRect: Qt.rect(0, 0, fastBlur.width, fastBlur.height) 
    } 
} 

當我移動到SwipeView下一個頁面,後臺撐靜態,但模糊不當然,因爲sourceRect區域沒有相對於其父母移動,只是父母相對於背景移動。模糊仍然是從原始位置取樣背景,而不是通過滑動視圖移動的新位置

因此,我拿起了一個事實,即我可以得到SwipeView.contentItem.contentX(感謝在QML: Mid-swipe position of item in SwipeView的答案! )但是在我的兩個頁面中,我必須根據它們的順序對contentX進行不同的計算。

我在這裏設置了一個示例模糊項目來展示我的意思。 https://github.com/ftab/BlurTest

具體而言,在與sourceRect - https://github.com/ftab/BlurTest/blob/master/Page1Form.qml#L23

sourceRect: Qt.rect(
       fastBlur.x - swipeView.contentItem.contentX, 
       fastBlur.y, 
       fastBlur.width, 
       fastBlur.height) 

這得到了模糊更新的預期的效果,同時它移動橫跨背景,但只適用,因爲模糊區域是刷卡的第一頁上視圖和contentX從0到640.如果這是在第二頁上,我必須做640 - contentX + fastBlur.x,然後如果我再次移動它,我必須再次調整,等等。

有沒有更好的方法來做到這一點,或者我幾乎堅持手編輯sourceRect,每當我添加另一個頁面或更改順序?

編輯:3頁例如完整的QML文件:

import QtQuick 2.7 
import QtQuick.Controls 2.0 
import QtQuick.Layouts 1.0 
import QtGraphicalEffects 1.0 

ApplicationWindow { 
    visible: true 
    width: 640 
    height: 480 

    SwipeView { 
     id: swipeView 
     anchors.fill: parent 
     currentIndex: tabBar.currentIndex 
     background: Image { 
      id: imgBackground 
      anchors.fill: parent 
      fillMode: Image.PreserveAspectCrop 
      source: "nature_1.jpg" 
     } 

     Item { 
      id: item1 

      Rectangle { 
       id: recFrost 
       anchors.fill: fastBlur 
       color: "white" 
      } 
      FastBlur { 
       id: fastBlur 
       anchors.fill: recControls 
       source: ShaderEffectSource { 
        sourceItem: imgBackground 

        sourceRect: Qt.rect(
            fastBlur.x - swipeView.contentItem.contentX, 
            fastBlur.y, 
            fastBlur.width, 
            fastBlur.height) 
       } 
       radius: 32 
       opacity: 0.55 
      } 
      Rectangle { 
       id: recControls 
       width: 364 
       height: 89 
       color: "#00000000" 
       anchors.bottomMargin: 8 
       anchors.horizontalCenter: parent.horizontalCenter 
       anchors.bottom: parent.bottom 

       Label { 
        text: qsTr("First page") 
        anchors.centerIn: parent 
       } 
      } 
     } 

     Item { 
      id: item2 

      Rectangle { 
       id: recFrost2 
       anchors.fill: fastBlur2 
       color: "white" 
      } 
      FastBlur { 
       id: fastBlur2 
       anchors.fill: recControls2 
       source: ShaderEffectSource { 
        sourceItem: imgBackground 

        sourceRect: Qt.rect(
            swipeView.width - swipeView.contentItem.contentX + fastBlur2.x, 
            fastBlur2.y, 
            fastBlur2.width, 
            fastBlur2.height) 
       } 
       radius: 32 
       opacity: 0.55 
      } 
      Rectangle { 
       id: recControls2 
       width: 364 
       height: 89 
       color: "#00000000" 
       anchors.centerIn: parent 

       Label { 
        text: qsTr("Second page") 
        anchors.centerIn: parent 
       } 
      } 
     } 

     Item { 
      id: item3 

      Rectangle { 
       id: recFrost3 
       anchors.fill: fastBlur3 
       color: "white" 
      } 
      FastBlur { 
       id: fastBlur3 
       anchors.fill: recControls3 
       source: ShaderEffectSource { 
        sourceItem: imgBackground 

        sourceRect: Qt.rect(
            swipeView.width * 2 - swipeView.contentItem.contentX + fastBlur2.x, 
            fastBlur3.y, 
            fastBlur3.width, 
            fastBlur3.height) 
       } 
       radius: 32 
       opacity: 0.55 
      } 
      Rectangle { 
       id: recControls3 
       width: 364 
       height: 89 
       color: "#00000000" 
       anchors.topMargin: 8 
       anchors.horizontalCenter: parent.horizontalCenter 
       anchors.top: parent.top 

       Label { 
        text: qsTr("Third page") 
        anchors.centerIn: parent 
       } 
      } 
     } 
    } 

    footer: TabBar { 
     id: tabBar 
     currentIndex: swipeView.currentIndex 
     TabButton { 
      text: qsTr("First") 
     } 
     TabButton { 
      text: qsTr("Second") 
     } 
     TabButton { 
      text: qsTr("Third") 
     } 
    } 
} 
+1

我無法想象你想要什麼,因爲我無法運行你的代碼。我不想遵循任何鏈接來回答你的問題,因爲這意味着一旦鏈接失效,問題對其他人就沒用了。請在此問題中包含[**最小,完整和可驗證示例**](https://stackoverflow.com/help/mcve)所需的所有內容。 – derM

+1

@derM增加了一個完整的QML文件,對不起,那個 – fury

回答

2

而是與swipeView.width增量做的,你可以用你的父頁面的x位置在SwipeView

sourceRect: Qt.rect(fastBlur2.x - swipeView.contentItem.contentX + item2.x, 
        fastBlur2.y, 
        fastBlur2.width, 
        astBlur2.height) 

或者你可以ItemmapToItem()。 但是,由於mapToItem是一個函數,當一個項目相對於另一個項目相對移動時,使用其返回值不會觸發綁定更新,因此我們必須輕輕提示QML引擎何時重新評估綁定。

sourceRect: { 
    swipeView.contentItem.contentX; /*here we access contentX in order to 
    force the reevaluation of the entire expression when contentX changes.*/ 
    return fastBlur3.mapToItem(swipeView, 0, 0, fastBlur3.width, fastBlur3.height); 
} 
+0

fastBlur2.x - swipeView.contentItem.contentX + fastBlur2.parent.x, – fury

相關問題