PageIndicator customization: interactive and with custom AND different indicator elements for each page



  • This question has also been asked on Stackoverflow but I'm thinking that due to its nature it would be more fruitful to do that here.

    The background story is as follows: I've just started learning QML and currently am working on a minimalistic UI for demonstration purposes of a device. For the main view I've decided to use SwipeView since it has a really nice structure, has the gesture-driven feel (I'll also be adding gesture support to my application using 3D motion detection) and also it can be used together with the PageIndicator, which supposedly can offer a very simplistic yet neat navigation. The mockup looks like this:

    enter image description here


    • Making PageIndicator's elements clickable and change page of SwipeView to respective index

    The first thing that I've noticed was that the interactive property doesn't seem to work. I tried with a default PageView without any modifications inside (except size of course) and 2-3 pages and a PageIndicator (without even the delegate). The documentation states that this property is supposed to make the PageIndicator's elements capable of acting upon being pressed that is change to the given page they are pointing at (unless we have more such elements than actual pages in the SwipeView). I don't know if this is a bug or I'm simply don't get the way it works. I'm leaning towards the second since I'm pretty new to QML and also even when the interactive property is set to true one still has to bind the PageIndicator to the SwipeView it's supposed to control. If anyone knows how to fix this please do tell. Currently I'm actually using a MouseArea and it's onClicked property inside the delegate of the PageIndicator to do that.

    • Using custom PageIndicator elements (Image components) for each page

    Next thing I'd like to do is use Image components for each element inside the PageIndicator. This will allow me to replace my current buttons that do the work of the PageIndicator (but working with these proofs to be quite clunky since I need to make a lot of checks for the state of each button).

    Currently I have the following code for my delegate property

    PageIndicator {
                 id: detailsViewIndicator
                 // ...
                 delegate: Image {
                     // detailsView is the `SwipeView` that the `PageIndicator` controls
                     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 is a list<Image> property containing three strings representing the QRC URLs of three image I Have:

    • Indicator image for page 1 in SwipeView:
      enter image description here
    • Indicator image for page 2 in SwipeView:
      enter image description here
    • Indicator image for page 2 in SwipeView:
      enter image description here

    The result I'm aiming for is

    [![enter image description here][2]][2]
    

    however I get the following behaviour:

    Swiping in the SwipeView (not clicking on the PageIndicator) leads to

    enter image description here

    and

    enter image description here

    This is only in one direction (index-wise from left to right). If I go backwards I get the same results but in the opposite order.

    Clicking makes things more interesting. In the screenshot below I've clicked on the second page indicator item (with qrc:/icons/qtlogo1.png as source for the Image) after the initialization:

    enter image description here

    Next I clicked on the third page indicator item:

    enter image description here

    After some more clicking I got:

    enter image description here

    which is actually what I wanted to have to begin with.

    This is obviously not how things should look and behave. A couple of questions concerning this issue:

    • Is it even possible to customize the PageIndicator to such an extent? The delegate is there to support a custom PageIndicator element however initializes all such elements with just the specified first image that is passed onto the source property by

      source = detailsViewIndicator.indicatorIcons[detailsView.currentIndex];

    • Is it possible to extract list elements and assign those to delegate? I have tried doing

      delegate: detailsViewIndicator.indicatorImages[detailsView.currentIndex]
      

    where indicatorImages is

    property list<Image> indicatorImages: [
       Image { source: "..." },
       Image { source: "..." },
       Image { source: "..." }
     ]
    

    but I get

    Unable to assign QQuickImage_QML_2 to QQmlComponent
    

    error. I was literally unable to find anything on this whatsoever. The reason why I want to do that is to initialize my Images once and after that just call them depending on the index that my PageIndicator is currently at.

    Regards,
    RB



  • Problem solved. Check the Stackoverflow post for details. In short - I did the assignment of the images incorrectly plus didn't actually properly handle the changing of the index of both the SwipeView and the PageIndicator.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.