我有一张带有背景图片的SwipeView。它有两个页面,两个页面都有一组控件和文本,我在它们下面放了一个类似iOS的模糊圆角矩形,这样它更容易阅读,但不会完全阻挡漂亮的背景
我在这个帖子的末尾发现了这个片段,导致我使用了一个白色矩形和一个半透明的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的答案!)但是在我的两个页面中,我必须根据内容对内容X进行不同的说明他们订购
我在这里设置了一个示例模糊项目,以显示我的意思。 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")
}
}
}
答案 0 :(得分:2)
您可以在swipeView.width
中使用父页面的x
位置,而不是以SwipeView
为增量进行操作:
sourceRect: Qt.rect(fastBlur2.x - swipeView.contentItem.contentX + item2.x,
fastBlur2.y,
fastBlur2.width,
astBlur2.height)
或者您可以Item
mapToItem()
。
但是,由于mapToItem
是一个函数,当一个项相对于另一个项移动时,使用它的返回值不会触发绑定更新,我们必须轻轻提示QML引擎何时重新评估绑定。 / p>
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);
}