Delegates QML-自定义PageIndicator以显示其指示的每个页面的图像
更新:为Delegates QML-自定义PageIndicator以显示其指示的每个页面的图像,delegates,qml,customization,Delegates,Qml,Customization,更新:为SwipeView添加了代码 我正试图定制页面指示器来完成我目前有三个按钮的任务 通过点击PageIndicator内的相应项目,可以更改页面(目前我有3个页面,每页一个按钮,点击onClicked可将SwipeView更改为预定义索引-否PageIndicator) 显示每个页面指示器项目的自定义图像(目前我有3个页面,每页一个按钮,带有自定义图像-无PageIndicator) MySwipeView具有以下结构: SwipeView { id: detailsView
SwipeView添加了代码
我正试图定制页面指示器
来完成我目前有三个按钮的任务
- 通过点击
PageIndicator
内的相应项目,可以更改页面(目前我有3个页面,每页一个按钮,点击onClicked
可将SwipeView
更改为预定义索引-否PageIndicator
)
- 显示每个页面指示器项目的自定义图像(目前我有3个页面,每页一个按钮,带有自定义图像-无
PageIndicator
)
MySwipeView
具有以下结构:
SwipeView {
id: detailsView
Layout.fillWidth: true
Layout.preferredHeight: layoutTopLevel.height * .9
Page {
id: captureViewPage
header: Text {
text: "Capture view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
}
Page {
id: helpViewPage
header: Text {
text: "Help view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
footer: TabBar {
id: helpViewSubCategories
currentIndex: 0
TabButton {
text: qsTr("Gestures")
}
TabButton {
text: qsTr("General")
}
}
}
Page {
id: settingsViewPage
header: Text {
text: "Settings view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
footer: TabBar {
id: settingsViewSubCategories
currentIndex: 0
TabButton {
text: qsTr("Language")
}
TabButton {
text: qsTr("Device")
}
}
}
}
SwipeView
和PageIndicator
(见下文)都是列布局的一部分,是子列:
ColumnLayout {
id: layoutDetailsAndMenu
spacing: 0
SwipeView { ... }
PageIndicator { ... }
}
首先,我研究了PageIndicator
的delegate
属性是如何工作的。例如,下面的QML代码
PageIndicator {
id: detailsViewIndicator
count: detailsView.count
currentIndex: detailsView.currentIndex
interactive: true
anchors.bottom: detailsView.bottom
anchors.bottomMargin: -40
anchors.horizontalCenter: parent.horizontalCenter
delegate: Rectangle {
implicitWidth: 15
implicitHeight: 15
radius: width
color: "#21be2b"
opacity: index === detailsView.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
Behavior on opacity {
OpacityAnimator {
duration: 100
}
}
}
}
生成以下绿色结果:
通过单击页面指示器中的相应项目,可以更改页面
由于某种原因,非活动
根本不起作用。我将引用文档说明此属性的功能:
交互式:bool
此属性保存控件是否是交互式的。互动的
页面指示器对按下按钮做出反应并自动更改当前页面
适当索引。默认值为false
我不知道这是一个bug还是我遗漏了什么,但即使没有通过委托
进行自定义,单击页面指示器项目也不会改变当前页面(这些项目的数量与页面数量相等,因此单击没有为其分配页面的索引是毫无疑问的)
因此,为了实现我的第一个愿望,我添加了一个MouseArea
:
PageIndicator {
// ...
delegate: Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
if(index !== detailsView.currentIndex) {
detailsView.setCurrentIndex(index);
}
}
}
}
}
正如您所看到的,我正在使用onClicked
事件处理程序(或任何这些东西的调用),并检查PageIndicator
的当前索引是否等于我的SwipeView
中的页面。如果不是这种情况,我使用setCurrentIndex(index)
将我的SwipeView
设置为所选索引
在我写了这篇文章之后,我非常满意它按照我的设想工作(尽管交互式的事情仍然困扰着我)。下一步是添加图像
显示每个页面指示器项目的自定义图像
首先,让我向您展示我希望事情看起来如何(这实际上是最终结果,但更多的是-稍后):
注意:我使用了我没有的Qt
徽标。用于演示目的
从左到右,QRC
URL是:
qrc:/icons/qtlogo.png
qrc:/icons/qtlogo1.png
qrc:/icons/qtlogo2.png
其来源如下:
delegate: Image {
source: detailsViewIndicator.indicatorIcons[detailsView.currentIndex]
height: 30
width: 30
opacity: index === detailsView.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
MouseArea {
anchors.fill: parent
onClicked: {
if(index !== detailsView.currentIndex) {
detailsView.setCurrentIndex(index);
source = detailsViewIndicator.indicatorIcons[detailsView.currentIndex];
}
}
}
}
其中指示符
是my页面指示符的变体
属性
:
property variant indicatorIcons: [
"qrc:/icons/qtlogo.png",
"qrc:/icons/qtlogo1.png",
"qrc:/icons/qtlogo2.png"
]
我已经为QRC
url使用了string
对象数组,因为这似乎是不可能的
delegate: detailsViewIndicator.indicatorImages[detailsView.currentIndex]
带有指示符号的图像
property list<Image> indicatorImages: [
Image { source: "..." },
Image { source: "..." },
Image { source: "..." }
]
第一次运行应用程序时,我得到:
这是因为最初选择的索引是0
,因此生成了带有源代码的图像
:“qrc:/icons/qtlogo.png”
,所有页面指示器项目都用它填充。如果我选择另外两个页面中的一个作为最初选择的页面,我将分别获得qrc:/icons/qtlog1.png
和qrc:/icons/qtlog2.png
在SwipeView
(不点击页面指示器
)中滑动会导致
及
这仅在一个方向上(从左到右按索引)。如果我倒退,我会得到相同的结果,但顺序相反
点击会让事情变得更有趣。在下面的屏幕截图中,我在初始化后单击了第二个页面指示项(带有qrc:/icons/qtlogo1.png
作为图像的源):
接下来,我单击了第三页的指示项:
再次点击后,我得到:
显然,事情不是这样的。我希望从开始到结束都能得到最终结果,无论哪个页面被刷走或页面指示器项目被点击
有人做过这样的事吗?这可能吗
由于某种原因,非活动的根本不起作用
我假设这是一个输入错误,因为使用交互式
属性对我有效(Qt5.7):
与第一个示例的简化版本一样:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
PageIndicator {
id: detailsViewIndicator
count: 3
currentIndex: 0
interactive: true
delegate: Rectangle {
implicitWidth: 15
implicitHeight: 15
radius: width
color: "#21be2b"
opacity: index === detailsViewIndicator.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
Behavior on opacity {
OpacityAnimator {
duration: 100
}
}
}
}
}
因此,如果SwipeView
没有改变页面,那么问题很可能就在那里,我们需要查看该代码
我希望从开始到结束都能得到最终结果,无论哪个页面被刷走或页面指示器项目被点击
我认为问题在于您用于图标数组的索引:
source: detailsViewIndicator.indicatorIcons[detailsView.currentIndex]
这将使用当前选定的索引,而您似乎希望使用该代理的索引:
source: detailsViewIndicator.indicatorIcons[index]
顺便说一下,指定图标源的一种更简单的方法是使用字符串连接(并为文件提供适当的名称以匹配):
在您添加的代码中,SwipeView
不会将其currentIndex
设置为PageIndicator
的currentIndex
。您可以这样做:
currentIndex: detailsViewIndicator.currentIndex
完整示例:
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
SwipeView {
id: detailsView
currentIndex: detailsViewIndicator.currentIndex
Layout.fillWidth: true
Layout.fillHeight: true
Page {
id: captureViewPage
header: Text {
text: "Capture view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
}
Page {
id: helpViewPage
header: Text {
text: "Help view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
footer: TabBar {
id: helpViewSubCategories
currentIndex: 0
TabButton {
text: qsTr("Gestures")
}
TabButton {
text: qsTr("General")
}
}
}
Page {
id: settingsViewPage
header: Text {
text: "Settings view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
footer: TabBar {
id: settingsViewSubCategories
currentIndex: 0
TabButton {
text: qsTr("Language")
}
TabButton {
text: qsTr("Device")
}
}
}
}
PageIndicator {
id: detailsViewIndicator
count: detailsView.count
currentIndex: detailsView.currentIndex
interactive: true
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
另一个注意事项:使用垂直锚(anchors.bottomsource: "qrc:/icons/qtlogo" + index + ".png"
currentIndex: detailsViewIndicator.currentIndex
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
anchors.fill: parent
SwipeView {
id: detailsView
currentIndex: detailsViewIndicator.currentIndex
Layout.fillWidth: true
Layout.fillHeight: true
Page {
id: captureViewPage
header: Text {
text: "Capture view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
}
Page {
id: helpViewPage
header: Text {
text: "Help view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
footer: TabBar {
id: helpViewSubCategories
currentIndex: 0
TabButton {
text: qsTr("Gestures")
}
TabButton {
text: qsTr("General")
}
}
}
Page {
id: settingsViewPage
header: Text {
text: "Settings view"
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 20
}
footer: TabBar {
id: settingsViewSubCategories
currentIndex: 0
TabButton {
text: qsTr("Language")
}
TabButton {
text: qsTr("Device")
}
}
}
}
PageIndicator {
id: detailsViewIndicator
count: detailsView.count
currentIndex: detailsView.currentIndex
interactive: true
anchors.horizontalCenter: parent.horizontalCenter
}
}
}