2016-11-16 4 views
0

Ich möchte meine Liste von Telefonnummern mit einem Feld ("Name") auf der linken Seite und einem anderen Feld ("Telefon") auf der rechten Seite ausrichten. Beim Versuch, Ankereigenschaften innerhalb des Delegaten zu binden, wird jedoch angegeben, dass das Delegatobjekt kein übergeordnetes Element der ListView-Komponente ist. Wie erreiche ich andere Komponenten vom Delegierten?Ausrichten von QML-Komponenten in einem Delegaten

Das ist mein QML-Code:

import QtQuick 2.7 
import QtQuick.Controls 2.0 

Item { 
    id: enclosing_area 
    width: 500 
    height: 300 
    ListModel { 
     id: dataModel 
     ListElement { 
      name: "John Smith" 
      phone: "1111-1111" 
     } 
     ListElement { 
      name: "Peter Poter" 
      phone: "2222-2222" 
     } 
     ListElement { 
      name: "Anna Lasalle" 
      phone: "3333-3333" 
     } 
    } 

    ListView { 
     id: list 
     width: enclosing_area.width 
     height: enclosing_area.height 
     model: dataModel 
     delegate: Rectangle { 
      width: enclosing_area.width 
      border.color: "red" 
      Label { 
       text: name 
       anchors.left: list.left 
      } 
      Label { 
       text: phone 
       anchors.right: list.right 
      } 
     } 
    } 
} 

qmlscene erzeugt die folgenden Fehler:

file:///LViewTest.qml:36:13: QML Label: Cannot anchor to an item that isn't a parent or sibling. 
file:///LViewTest.qml:32:13: QML Label: Cannot anchor to an item that isn't a parent or sibling. 
file:///LViewTest.qml:36:13: QML Label: Cannot anchor to an item that isn't a parent or sibling. 
file:///LViewTest.qml:32:13: QML Label: Cannot anchor to an item that isn't a parent or sibling. 
file:///LViewTest.qml:36:13: QML Label: Cannot anchor to an item that isn't a parent or sibling. 
file:///LViewTest.qml:32:13: QML Label: Cannot anchor to an item that isn't a parent or sibling. 

Linien 32 und 32 sind "anchors.left" und "anchors.right" Aussagen. Wie binde ich in meinem Fall an Eigenschaften in anderen Objekten vom Delegaten?

Antwort

3

Zunächst:

Es wäre Konvention Ihre enclosing_arearoot statt anzurufen.
Zweitens, wenn Sie nicht an einem Geschwister verankern, verwenden Sie nicht die id des Objekts, das Sie verankern möchten, aber verwenden Sie parent.

Dies verhindert, dass Sie Ihre Fehler erhalten, da - was Sie versuchen zu tun - nicht an die Eltern der Label s, sondern an ihre parent s parent verankert ist.
Die parent der Label wäre die Rectangle in Ihrer delegate.

ListView { 
    id: list // <- This is not the parent of the Labels, but of the delegateRectangle 
    width: enclosing_area.width  // works 
    height: enclosing_area.height // works 
    // anchors.fill: parent   <- would do the same, more flexible, and only one line. 
    model: dataModel 
    delegate: Rectangle { 
     id: delegateRectangle // <--- This is the parent of the two Labels 
     width: enclosing_area.width 
     height: 30 // <- a heightis necessary. 
        // As the objects are repositioned you need to set it explicitely 
        // and can't use anchoring. You could use the 
        // implicit height of it's children, to make it nice 
     border.color: "red" 
     Label { 
      text: name 
      anchors.left: delegateRectangle.left // this would work instead. 
               // list.left woudl try to anchor to the 'grandparent' 
     } 
     Label { 
      text: phone 
      anchors.right: parent.right // this would be the reccomended way. 
             // Would also anchor to delegateRectangle 
     } 
    } 
} 

Warum sollten Sie lieber parent anstatt Ihre parent s id zu verankern?
Das Objekt wird (fast) immer ein visuelles Elternelement haben, aber dieses visuelle Elternelement könnte sich ändern. Entweder weil Sie eine zusätzliche Ebene im Code hinzufügen, später - oder sogar während der Laufzeit, indem Sie sie erneut bereitstellen. Sie müssten also immer auch die Anker aktualisieren.
Daher löst die Verankerung an parent einen einfachen Fehler.

1

Nutzen Sie die Vorteile von Ankern, anstatt zu versuchen, die Größe eines untergeordneten Elements so zu codieren, dass es dem übergeordneten Element entspricht. Dadurch können Sie Anker ganz unten verwenden. (Verwenden Sie in ähnlicher Weise Ankermargen anstelle von fest codierten x, y-Werten). Sie erhalten viele andere Vorteile mit Ankern.

ListView { 
     id: list 
     anchors.fill: parent 
     model: dataModel 
     delegate: Rectangle { 
      anchors.left: parent.left 
      anchors.right: parent.right 
      height: 50  // you need a height otherwise all rows are on the same line 
      border.color: "red" 
      Label { 
       text: name 
       anchors.left: parent.left 
      } 
      Label { 
       text: phone 
       anchors.right: parent.right 
      } 
     } 
    } 
} 
Verwandte Themen