2016-07-22 20 views
2

zeigt UPDATE: Added-Code für SwipeViewQML - Customizing PageIndicator ein Bild für jede Seite zu zeigen, es

Ich versuche, die PageIndicator zu tun, was anpassen derzeit Ich habe drei Tasten

    nämlich tun
  • Machen Sie es möglich, Seiten zu wechseln, indem Sie auf den entsprechenden Artikel innerhalb der PageIndicator klicken (zur Zeit habe ich 3 Seiten, eine Taste pro Seite mit onClicked eingestellt, um die SwipeView zu einem vordefinierten Index zu ändern - no PageIndicator)
  • Anzeige benutzerdefiniertes Bild für jeden Seite Indikatoren Artikel (derzeit Ich habe 3 Seiten, einen Knopf pro Seite mit einem benutzerdefinierten Bild - keine PageIndicator)

Meine SwipeView hat die folgende Struktur:

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") 
      } 
     } 
    } 
} 

sowohl die SwipeView und die PageIndicator (siehe unten) sind Teil eines ColumnLayout und sind sublings:

ColumnLayout { 
     id: layoutDetailsAndMenu 
     spacing: 0 
     SwipeView { ... } 
     PageIndicator { ... } 
} 

Zuerst habe ich recherchiert, wie die Eigenschaft der PageIndicator funktioniert. die folgenden QML-Code zum Beispiel

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 
         } 
        } 
       } 
     } 

erzeugt folgende grünlich Ergebnis:

enter image description here


Machen Sie es möglich, die Seiten zu wechseln, indem Sie in der PageIndicator auf dem jeweiligen Element klicken

Aus irgendeinem Grund die inactive d funktioniert überhaupt nicht. Ich werde in der Dokumentation zitieren, was diese Eigenschaft tun soll:

interaktive: Bool

Diese Eigenschaft enthält, ob die Steuerung interaktiv ist. Ein interaktiver Seitenindikator reagiert auf Drücken und ändert automatisch den aktuellen Index entsprechend. Der Standardwert ist false.

Ich weiß nicht, ob dies ein Fehler ist oder ich etwas fehlt, aber auch ohne die Anpassung über delegate Klick auf eine Artikelseite Indikator tut NICHT Änderung der aktuellen Seite (die Anzahl dieser Elemente macht gleich der Anzahl der Seiten, so dass ein Klick auf einen Index, dem keine Seite zugeordnet ist, nicht in Frage kommt).

Um also mein erster Wunsch wahr zu machen habe ich ein MouseArea:

PageIndicator { 
      // ... 
      delegate: Rectangle { 
       MouseArea { 
        anchors.fill: parent 
        onClicked: { 
         if(index !== detailsView.currentIndex) { 
          detailsView.setCurrentIndex(index); 
         } 
        } 
       } 
      } 
    } 

Wie Sie sehen, ich bin mit dem onClicked Event-Handler (oder was auch immer diese Dinge genannt werden) und prüfen, ob die aktueller Index der PageIndicator entspricht der Seite in meiner SwipeView. Wenn das nicht der Fall ist, verwende ich setCurrentIndex(index), um meinen SwipeView auf den ausgewählten Index zu setzen.

Nachdem ich das geschrieben hatte, war ich ziemlich zufrieden, dass es so funktionierte, wie ich es mir vorstellte (obwohl mich die interactive Sache immer noch stört). Das nächste, was war es, die Bilder hinzufügen ...


Anzeige benutzerdefiniertes Bild für jede Seite Indikator Artikel

Zunächst möchte ich Ihnen zeigen, wie ich die Dinge möchte aussehen (das ist eigentlich die letzte Ergebnis aber mehr dazu - später auf der Linie):

HINWEIS: Ich habe das Qt Logo verwendet, das ich nicht besitze. Es ist zu Demonstrationszwecken

enter image description here

aus den QRC URLs sind von links nach rechts:

  • qrc:/icons/qtlogo.png

    enter image description here

  • qrc:/icons/qtlogo1.png

    enter image description here

  • qrc:/icons/qtlogo2.png

    enter image description here

Die Quelle hierfür ist wie folgt:

  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]; 
         } 
        } 
       } 
      } 

wo indicatorIcons ist eine variant Eigenschaft meiner PageIndicator:

property variant indicatorIcons: [ 
       "qrc:/icons/qtlogo.png", 
       "qrc:/icons/qtlogo1.png", 
       "qrc:/icons/qtlogo2.png" 
      ] 

Ich habe eine Reihe von string Objekte für die QRC URLs verwendet, da es unmöglich scheint

delegate: detailsViewIndicator.indicatorImages[detailsView.currentIndex] 

mit indicatorImages sein

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

Die Fragen, die ich bin zu tun Ich habe das Gefühl, dass es etwas mit dem list Problem zu tun hat, das ich beschrieben habe über.Mit dem Code

  delegate: Image { 
       source: detailsViewIndicator.indicatorIcons[detailsView.currentIndex] 
       // ... 
      } 

erste Mal, dass ich meine Anwendung ausführen ich:

enter image description here

Dies ist aufgrund der Tatsache, dass der ursprünglich ausgewählten Index 0 so ein Image mit source: "qrc:/icons/qtlogo.png" erzeugt wird, ein All Seitenindikatorelemente werden damit gefüllt. Wenn ich eines der beiden anderen als die ursprünglich ausgewählte Seite auswähle, bekomme ich qrc:/icons/qtlogo1.png bzw. qrc:/icons/qtlogo2.png.

Swiping im SwipeView (nicht Klick auf den PageIndicator) führt zu

enter image description here

und

enter image description here

Diese nur in eine Richtung (Index weise von links nach Recht). Wenn ich rückwärts gehe, bekomme ich die gleichen Ergebnisse, aber in umgekehrter Reihenfolge.

Anklicken macht die Dinge interessanter. In der Abbildung unten ich auf der zweiten Seite Indikator Artikel geklickt haben (mit qrc:/icons/qtlogo1.png als Quelle für die Image) nach der Initialisierung:

enter image description here

Next ich auf der dritten Seite Indikator Artikel geklickt:

enter image description here

Nach weiterem Klick ich bekam:

enter image description here

Offensichtlich ist dies nicht so, wie die Dinge funktionieren sollen. Ich möchte das Endergebnis die ganze Zeit von Anfang bis Ende haben und egal welche Seite weggeschwemmt wurde oder ob der Seitenindikator geklickt wurde.

Hat jemand so etwas getan? Ist das überhaupt möglich?

Antwort

2

Aus irgendeinem Grund die inaktiv auf allen Ich gehe davon aus

nicht funktioniert dies ein Tippfehler ist, wie mit der interactive Eigenschaft funktioniert für mich (Qt 5.7):

import QtQuick 2.7 
import QtQuick.Controls 2.0 

ApplicationWindow { 
    visible: true 

    PageIndicator { 
     count: 3 
     interactive: true 
     onCurrentIndexChanged: print(currentIndex) 
    } 
} 

Wie funktioniert eine vereinfachte Version des ersten Beispiels:

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 
       } 
      } 
     } 
    } 
} 

Also, wenn die SwipeView ändert nicht die Seiten, das Problem ist wahrscheinlich dort, und wir müssten diesen Code sehen.

Ich möchte das Endergebnis die ganze Zeit von Anfang bis Ende haben und egal welche Seite weggeschwemmt wurde oder Seitenindikator Element geklickt.

Ich denke, das Problem mit dem Index ist, den Sie für das Symbol Array:

source: detailsViewIndicator.indicatorIcons[detailsView.currentIndex] 

, dass die aktuell ausgewählte Index ist verwenden, während es scheint, wie Sie den Index dieser Delegat verwenden möchten :

source: detailsViewIndicator.indicatorIcons[index] 

By the way, wäre ein einfacher Weg, um die Symbol Quelle der Angabe String-Verkettung zu verwenden (und Ihre Dateien den entsprechenden Namen geben übereinstimmen):

source: "qrc:/icons/qtlogo" + index + ".png" 

Im Code, den Sie hinzugefügt, die SwipeView stellt nicht seine currentIndex zum currentIndex des PageIndicator. Sie können wie folgt vorgehen:

currentIndex: detailsViewIndicator.currentIndex 

Das vollständige Beispiel:

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 
     } 
    } 
} 

Noch ein Hinweis: vertikale Dübeln (anchors.bottom, anchors.top) in einem ColumnLayout wird nicht funktionieren. Nur horizontale Anker können im unmittelbaren Kind eines vertikalen Layouts verwendet werden und umgekehrt.

+0

Wird meine Frage aktualisieren. Wie für die Tatsache, dass es in Ihrem Fall funktioniert - muss der 'PageIndicator' ein Kind des' SwipeView' sein oder kann es ein Subling sein? In meinem Fall ist es tatsächlich ein Subling, also vielleicht ist das der Grund ... – rbaleksandar

+0

Und ja, 'inaktiv' ist ein Tippfehler. : D – rbaleksandar

+0

Sie haben einen upvote von mir für die Quelle: "qrc:/icons/qtlogo" + index + ".png" 'was eine wirklich gute Idee ist. Die Bilder werden jetzt richtig angezeigt! Das Klicken ist immer noch ein Problem. : 3 – rbaleksandar