2017-03-12 5 views
0

Ich versuche, die folgende GUI in QML zu implementieren und zu Schwierigkeiten, zu verstehen, wie man richtig durch verschiedene Seiten der Anwendung zu navigieren.Seitennavigation in QML

enter image description here

Es gibt drei Schaltflächen im Hauptmenü. Wenn der Benutzer auf die Schaltfläche "Aktor" klickt, wechselt die Benutzeroberfläche zur "Darstelleransicht", in der der Benutzer zwischen der Miniaturansicht und der Listenansicht wechseln kann. Wenn der Benutzer auf einen der Akteure klickt, wechselt die Benutzeroberfläche zur Darsteller-Detailansicht: Eine Ansicht, in der eine Filmansicht "verschachtelt" ist, in der alle Darstellerfilme aufgelistet sind.

Ich versuche, diese StackView mit umzusetzen.

So lebt mein StackView im Hauptmenü (main.qml), wenn der Benutzer auf eine der Schaltflächen klickt der onClicked Ereignis auf den Stapel die richtige Ansicht schiebt.

ActorsView.qml besteht aus einem internen StackView (wahrscheinlich eine schlechte Idee) und 2 Tasten, die zwischen Daumen und Detailansicht wechseln. Dies geschieht durch Drücken der Thumb- oder Detailansicht auf den lokalen Stapel.

DetailView.qml und ThumbView.qml Funktion genau das gleiche, obwohl anders aussehen. Hier ist, wo ich in Schwierigkeiten geriet. Ich möchte, dass die Hauptansicht benachrichtigt wird, wenn ein Klickereignis in der Detail- oder Thumb-Ansicht auftritt. Damit könnte es (basierend auf dem Ereignis Informationen weitergegeben) wissen, welche Ansicht auf den Haupt-Stack drückt. Wenn der Benutzer beispielsweise auf Akteur1 klickt, kann das Hauptmenü die Akteurdetailansicht für Akteur 1 auf den Stapel schieben.

Leider weiß ich nicht, wie sie die Ereignisse zu ‚fangen‘, die in verschachtelten Komponenten in dem übergeordneten Elemente feuern.

Ich habe erst vor ein paar Wochen begonnen, mit QML und QT herumzuspielen, und wäre glücklich zu hören, dass mein Ansatz falsch ist und dass es viel bessere Möglichkeiten gibt, um das zu erreichen, was ich will. Leider ist dies die einzig mögliche Option, die ich bisher gefunden habe.

main.qml:

ApplicationWindow { 
    title: qsTr("Hello World") 
    width: 1280 
    height: 720 
    visible: true 
    id: mainWindow 

    Component{ 
     id: homeScreen 
     Rectangle{ 
      height: 500 
      width: 500 
      color:"blue" 
      anchors.centerIn: mainWindow 

      Text { 
       anchors.centerIn: parent 
       text: qsTr("Home") 
       font.pixelSize: 40 
      } 
     } 
    } 


    Component{ 
     id: actorsView 
     ActorsView{ 
      view: stack 
     } 
    } 


    Component{ 
     id: moviesView 
     MoviesView{ 
      view: stack 
     } 
    } 

    ColumnLayout{ 
     RowLayout{ 
      Layout.fillWidth: true 


      Button{ 
       text: "Back" 
       onClicked: stack.pop() 

      } 


      Button{ 
       text: "actor view" 
       onClicked: stack.push(actorView) 
      } 

      Button{ 
       text: "movie view" 
       onClicked: stack.push(moviesView) 

      } 

     } 

     StackView { 
      id: stack 
      initialItem: homeScreen 
      Layout.fillHeight: true 
      Layout.fillWidth: true 

     } 

    } 

ActorsView.qml:

Item { 
    property StackView view 

    Component { 
     id: actorDetailView 
     DetailView { 
      name: "actorDetailView" 
      text: "Actor" 
     } 
    } 

    Component { 
     id: actorThumbView 
     ThumbView { 
      name: "actorThumbView" 
      text: "Actor" 
     } 
    } 

    ColumnLayout { 

     RowLayout { 

      Text { 
       text: "Actor view" 
       Layout.fillWidth: true 
       horizontalAlignment: Text.AlignHCenter 
      } 

      Button { 
       text: "Detail" 
       onClicked: internalStack.push(actorDetailView) 
      } 
      Button { 
       text: "Thumb" 
       onClicked: internalStack.push(actorThumbView) 
      } 

      Button { 
       text: "back" 
       onClicked: internalStack.pop() 
      } 

      Button { 
       text: "depth: " + internalStack.depth 

      } 
     } 

     StackView { 
      id: internalStack 
      initialItem: { 
       console.log(internalStack.depth) 
       internalStack.initialItem = actorThumbView 
      } 
      Layout.fillHeight: true 
      Layout.fillWidth: true 
     } 
    } 
} 

ThumbView.qml:

Item { 
    property string name: "thumbView" 
    property string text 
    property int counter: 0 
    id:thumbView 
    signal thumbPressed (string pressedName) 

    GridLayout { 
     columnSpacing: 10 
     rowSpacing: 10 
     width: parent.width 

     Repeater { 
      model: 16 
      Rectangle { 

       width: 200 
       height: 300 
       color: "grey" 
       Text { 
        id: lable 
        text: text 
        anchors.centerIn: parent 
       } 

       MouseArea { 
        anchors.fill: parent 
        onClicked: { 
         var tag = lable.text 
         console.log("You have clicked " + tag) 

         thumbView.thumbPressed(tag) 
        } 
       } 

       Component.onCompleted: { 
        counter = counter + 1 
        lable.text = text + " " + counter 
       } 
      } 
     } 
    } 

Antwort

2

Das eigentlich ist ein gängiger Ansatz zur Strukturierung einer QML-Anwendung, also nein, es ist nicht alles schlecht! Verschachtelte StackViews sind eine leistungsstarke Möglichkeit, den Unterinhalt einer Seite zu verwalten, fügen jedoch sicher eine Ebene in Ihrer App-Struktur hinzu. Es wird einfacher gemacht, indem Sie Ihren eigenen Page Artikel erstellen und die Navigation und Interaktion nach Ihren Wünschen neu definieren.

ist es verschiedene Möglichkeiten Signal in verschachtelten Komponenten zu handhaben. Am einfachsten: Rufen Sie einen identifizierten Artikel in der Hierarchie auf. Auf lokale und übergeordnete Elemente in QML kann direkt von id zugegriffen werden, auch wenn diese nicht in derselben QML-Datei enthalten sind. Was dies zulässt, hat natürlich den Nachteil, dass eine Kopplung zwischen Ihren Seiten oder Komponenten und dem Rest Ihrer Anwendung entsteht.

ApplicationWindow { 
    id: mainWindow 

    function pushPage(page) { 
     stack.push(page) 
    } 
    function showActor(id) { 
     ... 
    } 

    // ... 
} 

In Ihrer Seite einfach ...

MouseArea { 
    onClicked: { 
     mainWindow.showActor(index) 
    } 
} 

etwas mehr modular Um dies zu erreichen, können Sie StackView currentItem, Signale setzen, Connections und Binding Elemente nur einige zu nennen, oder eine Schnittstelle in QML und/oder C++ implementieren Ihre Navigation zu verwalten.

Es gibt definitiv eine Menge Möglichkeiten je nach Zielarchitektur, versuchen & Lernen macht es perfekt!

+0

Vielen Dank! Ich verwende die von Ihnen vorgeschlagene Methode, bei der Sie die Navigationsfunktionen im Stammverzeichnis deklarieren und sie aus den Elementen in der Hierarchie aufrufen. – Curtwagner1984