2015-10-06 2 views
3

Я пытаюсь добавить ячейки в свой GridLayout с помощью Repeater. Мои данные хранятся в модели и содержит два свойства для каждого элемента:Заполнение GridLayout с помощью ретранслятора

  • Title
  • Value

Моя цель состоит в том, чтобы получить GridLayout, содержащий Title в первой ячейке и Value во втором ячейки каждой строки.

GridLayout { 
    id: someId 
    columns: 2 
    rowSpacing: 5 
    columnSpacing: 5 
    anchors.margins: 5 
    anchors.left: parent.left 
    anchors.right: parent.right 

    Repeater { 
     model: myModel 
     Label { 
      text: modelData.title 
     } 
     TextArea { 
      text: modelData.value 
     } 
    } 
} 

Но QML Repeater допускает только один элемент. Любые идеи, как я могу получить макет, который я хочу?

+------------+---------------------------------------+ 
|   |          | 
| title0 |   value0      | 
|   |          | 
|   |          | 
+------------+---------------------------------------+ 
|   |          | 
|   |          | 
| title1 |   value1      | 
|   |          | 
|   |          | 
+------------+---------------------------------------+ 
|   |          | 
| title2 |   value2      | 
|   |          | 
|   |          | 
+------------+---------------------------------------+ 

ответ

9

Вы можете просто использовать два Repeater сек в GridLayout, следующим образом:

import QtQuick 2.5 
import QtQuick.Window 2.2 
import QtQuick.Layouts 1.1 
import QtQuick.Controls 1.4 

Window { 
    width: 600; height: 400; visible: true 

    GridLayout { 
     id: grid 
     anchors.fill: parent 
     columns: 2 
     rowSpacing: 5 
     columnSpacing: 5 
     anchors.margins: 5 
     // example models 
     property var titles: [ "title1", "title2", "title3", "title4", "title5" ] 
     property var values: [ "value1", "value2", "value3", "value4", "value5" ] 

     Repeater { 
      model: grid.titles 
      Label { 
       Layout.row: index 
       Layout.column: 0 
       Layout.fillWidth: true 
       Layout.fillHeight: true 
       text: modelData 
      } 
     } 

     Repeater { 
      model: grid.values 
      TextArea { 
       Layout.row: index 
       Layout.column: 1 
       Layout.fillWidth: true 
       Layout.fillHeight: true 
       text: modelData 
      } 
     } 
    } 
} 

Параметр index находится в свободном доступе и хранить текущую строку модели.

Используя прикрепленное свойство Layout.fillWidth, вы можете управлять width одного столбца.

Конечно, каждая ячейка, принадлежащая столбцу, имеет одинаковый размер всех других ячеек этого столбца, в отличие от того, что происходит с использованием двух компонентов Column.

Это решение имеет несколько недостатков, но это хорошо, если ваша цель заключается главным образом в том, чтобы печатать простые данные с модели.

+0

Это именно то, что я хочу. Ключ - это индекс. Отлично!!! – Marcus

3

Принцип представления модели предполагает, что каждый узел модели отображает другой объект компонента-делегата. Поэтому я советую вам послушать комментарий @ BaCaRoZzo и сделать это с Column вместо GridLayout. Конечно, QML очень гибкий, и вы можете сделать что-то подобное:

Component { 
    id: labelDelegate 
    Label { text: myList.get(_index/2).title } 
} 

Component { 
    id: textAreaDelegate 
    TextArea { text: myList.get(_index/2).value } 
} 

ListModel { 
    id: myList 
    ListElement {title: "title1"; value: "value1"} 
    ListElement {title: "title2"; value: "value2"} 
    ListElement {title: "title3"; value: "value3"} 
} 

GridLayout { 
    anchors.fill: parent 
    columns: 2 
    Repeater { 
     model: myList.count * 2 
     delegate: Loader { 
      property int _index: index 
      sourceComponent: { 
       if(index % 2) 
        return textAreaDelegate; 
       else 
        return labelDelegate; 
      } 
     } 
    } 
} 

но это слишком странно, чтобы использовать его в реальном проекте.

+0

Хорошо, спасибо. Я попробую решение на основе столбцов, как это предлагает @BaCaRoZzo. Даже я не уверен, что результат - это то, что я хочу. Я думаю, что первая ячейка каждой строки будет иметь разную ширину. Давайте посмотрим, не ошибаюсь ли я (надеюсь, что так ^^) – Marcus

+0

Предлагаемая версия для заполнения столбцов работает довольно хорошо, но результирующий макет - это не то, что я хочу. Первая ячейка каждой строки имеет разную ширину. Так что это не решение проблемы. Я попробую проводное решение @folibis ... если оно работает, оно недостаточно проводное :) – Marcus

+0

Naaah, не используйте его, я разместил его как пример того, как вы не должны этого делать. Таким образом, в случае использования 'Column' вы можете установить одинаковую ширину для каждой« Label ». Или, вернее, вам следует рассмотреть модель. – folibis

0

Вы можете использовать GridLayout.flow, чтобы указать, в каком порядке ячейки должны быть заполнены, то есть строка- (GridLayout.LeftToRight) или по столбцам (GridLayout.TopToBottom). Обратите внимание, что при использовании GridLayout.TopToBottom вы должны указать number of rows.

Используя это решение, то (упрощенный) пример skypjack станет:

import QtQuick 2.5 
import QtQuick.Window 2.2 
import QtQuick.Layouts 1.1 
import QtQuick.Controls 1.4 

Window { 
    width: 600; height: 400; visible: true 

    GridLayout { 
     anchors.fill: parent 

     % specify the flow and number of rows 
     flow: GridLayout.TopToBottom 
     rows: repeater.count 

     Repeater { 
      id: repeater 
      model: [ "title1", "title2", "title3", "title4", "title5", "title6" ] // example model 
      Label { 
       Layout.fillWidth: true 
       Layout.fillHeight: true 
       text: modelData 
      } 
     } 

     Repeater { 
      model: [ "value1", "value2", "value3", "value4", "value5", "value6" ] // example model 
      TextArea { 
       Layout.fillWidth: true 
       Layout.fillHeight: true 
       text: modelData 
      } 
     } 
    } 
} 
Смежные вопросы