更新:添加了SwipeView
的代码
我正在尝试自定义PageIndicator
以执行我目前拥有的三个按钮,即
通过单击PageIndicator
内的相应项来更改页面(当前我有3页,每页一个按钮,其中onClicked
设置为将SwipeView
更改为预定义索引-无需PageIndicator
)
显示每个页面指示符项的自定义图像(当前我有3页,每页带有一个自定义图像的按钮-没有PageIndicator
)
我的SwipeView
具有以下结构:
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
的一部分,并且是子类:ColumnLayout {
id: layoutDetailsAndMenu
spacing: 0
SwipeView { ... }
PageIndicator { ... }
}
首先,我研究了
delegate
的PageIndicator
属性如何工作。例如以下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
}
}
}
}
产生以下绿色结果:
通过单击
PageIndicator
内的相应项目可以更改页面由于某些原因,
inactive
根本不起作用。我将引用文档说明此属性的作用:互动式:布尔
此属性保存控件是否为交互式。互动式
页面指示器对压力做出反应并自动更改当前
适当索引。默认值为false。
我不知道这是一个错误还是丢失了某些东西,但是即使没有通过
delegate
进行自定义,也无法单击页面指示器项来更改当前页面(这些项的数量等于页面数,因此单击没有分配页面的索引是毫无疑问的)。因此,为了实现我的第一个愿望,我添加了
MouseArea
: PageIndicator {
// ...
delegate: Rectangle {
MouseArea {
anchors.fill: parent
onClicked: {
if(index !== detailsView.currentIndex) {
detailsView.setCurrentIndex(index);
}
}
}
}
}
如您所见,我正在使用
onClicked
事件处理程序(或任何此类调用),并检查PageIndicator
的当前索引是否等于SwipeView
中的页面。如果不是这种情况,我可以使用setCurrentIndex(index)
将SwipeView
设置为所选索引。写完这篇文章后,我很满意它能按我的设想工作(尽管
interactive
仍然困扰着我)。接下来是添加图像...显示每个页面指示器项目的自定义图像
首先,让我向您展示我希望外观如何(这实际上是最终结果,但更多内容-稍后讲):
注意:我使用了我不拥有的
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];
}
}
}
}
其中
indicatorIcons
是我的variant
的PageIndicator
属性: property variant indicatorIcons: [
"qrc:/icons/qtlogo.png",
"qrc:/icons/qtlogo1.png",
"qrc:/icons/qtlogo2.png"
]
我已经为
string
URL使用了QRC
对象数组,因为似乎无法做到delegate: detailsViewIndicator.indicatorImages[detailsView.currentIndex]
indicatorImages
被property list<Image> indicatorImages: [
Image { source: "..." },
Image { source: "..." },
Image { source: "..." }
]
我遇到的问题与图像的实际加载有关,并且我感觉到它与上述的
list
问题有关。用代码 delegate: Image {
source: detailsViewIndicator.indicatorIcons[detailsView.currentIndex]
// ...
}
第一次运行应用程序时,我得到:
这是由于以下事实:最初选择的索引是
0
,所以生成了带有Image
的source: "qrc:/icons/qtlogo.png"
,并且所有页面指示符项均已填充。如果我选择其他两个页面之一作为最初选择的页面,则分别得到qrc:/icons/qtlogo1.png
和qrc:/icons/qtlogo2.png
。在
SwipeView
中滑动(不单击PageIndicator
)会导致和
仅在一个方向上(从左到右为索引方向)。如果我向后走,我得到的结果却是相反的。
单击使事情变得更有趣。在下面的屏幕快照中,我在初始化后单击了第二个页面指示符项(以
qrc:/icons/qtlogo1.png
作为Image
的源):接下来,我单击了第三页指示符项:
再点击几下,我得到:
显然,这不是应该工作的方式。我希望从头到尾始终保持最终结果,无论哪一页被刷掉或单击页面指示符项。
有人做过这样的事情吗?这有可能吗?
最佳答案
由于某种原因,非活动状态根本不起作用
我假设这是一个错字,因为使用interactive
属性对我有效(Qt 5.7):
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
PageIndicator {
count: 3
interactive: true
onCurrentIndexChanged: print(currentIndex)
}
}
第一个示例的简化版本也是如此:
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]
顺便说一句,指定图标源的一种更简单的方法是使用字符串串联(并为文件提供适当的命名以进行匹配):
source: "qrc:/icons/qtlogo" + index + ".png"
在您添加的代码中,
SwipeView
并未将其currentIndex
设置为currentIndex
的PageIndicator
。您可以这样做: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.bottom
中使用垂直锚点(anchors.top
,ColumnLayout
)将不起作用。在垂直布局的直接子级中只能使用水平锚,反之亦然。
关于delegates - QML-自定义PageIndicator以为其指示的每个页面显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38520083/