2015-04-17 2 views
1

Я хочу создать в QML телевизионный расписание, где вертикальная ось представляет собой список каналов, а горизонтальная ось основана на времени. Например, что-то вродеДвумерный стол с вложенными прокручиваемыми областями в QML

http://zappware.com/wbdsgn/wp-content/uploads/2014/08/Zuku_v03_EPG_01_Caslte.jpg

Изначально я создал

  • вертикальный ListView с
    • моделью = списком каналов
    • делегата = горизонтальной ListView
  • каждый горизонтальный ListView имеет
    • модели = список событий
    • делегата = вашу деталь, где ширина пропорциональна длительности события

До сих пор так хорошо. Единственным недостатком является то, что горизонтальные списки ListViews прокручиваются один за другим, пока они должны прокручиваться вместе.

Таким образом, свойство contentX каждого горизонтального ListView должно быть привязано к свойству contentX перемещающегося/перемещающегося горизонтального ListView. Обратите внимание, что это привязка динамическое: при щелчке в первой строке все остальные строки должны связываться с содержимым X первой строки. Но это должно быть изменено при щелчке во второй строке.

Любые советы о том, как это можно сделать?

Я попробовал несколько иной подход

  • создавая Flickable позицию в верхней части вертикальной ListView (с contentWidth полное время-окна).
  • связывания каждый горизонтальный ListView к contentX этого Flickable (это статическое связывание)

Это привело к хорошей синхронной прокрутки, но я до сих пор есть некоторые проблемы

  • я должен был сделать некоторые трюки чтобы щелкнуть только горизонтально или вертикально, но не оба:
  • Я не могу больше нажимать на отдельные события; Я предполагаю, что события перехватываются Flickable
  • Я также не уверен в влиянии памяти такого Проникающего с огромным контентом contentWidth?

Отзыв оценен!

ответ

3

Я бы сказал, что у каналов есть только один вертикальный список. Но только названия каналов, а не настоящие программы. Вместо горизонтального представления для программ вы можете комбинировать их все вместе одним щелчком, используя время и продолжительность начала, чтобы компоновать программы в движущихся, привязывая их свойства x и width к первому.

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

Вот краткий пример:

ApplicationWindow { 
    id: main 
    width: 500 
    height: 100 
    visible: true 
    color: "white" 

    ListModel { 
     id: modC 
     ListElement { name: "Ch1" } 
     ListElement { name: "Ch2" } 
     ListElement { name: "Ch3" } 
    } 

    ListModel { 
     id: modP1 
     ListElement { name: "p1"; start: 0; duration: 6 } 
     ListElement { name: "p2"; start: 6; duration: 6 } 
     ListElement { name: "p3"; start: 12; duration: 6 } 
     ListElement { name: "p4"; start: 18; duration: 6 } 
    } 
    ListModel { 
     id: modP2 
     ListElement { name: "p1"; start: 0; duration: 12 } 
     ListElement { name: "p2"; start: 12; duration: 12 } 
    } 
    ListModel { 
     id: modP3 
     ListElement { name: "p1"; start: 0; duration: 8 } 
     ListElement { name: "p2"; start: 8; duration: 8 } 
     ListElement { name: "p3"; start: 16; duration: 8 } 
    } 

    property var subMod : [ modP1, modP2, modP3 ] 

    Component { 
     id: progDelegate 
     Rectangle { 
      property var source 
      x: source.start * 50 
      width: source.duration * 50 
      height: 50 
      color: "lightblue" 
      border.color: "black" 
      Text { 
       text: source.name 
      } 
     } 
    } 

    Row { 
     anchors.fill: parent 
     ListView { 
      id: list 
      height: parent.height 
      width: 100 
      model: modC 

      delegate: Item { 
       width: 100 
       height: 50 
       Rectangle { 
        anchors.fill: parent 
        color: "red" 
        border.color: "black" 
        Text { 
         anchors.centerIn: parent 
         text: name 
        } 
       } 
       Component.onCompleted: { 
        var mod = subMod[index] 
        for (var i = 0; i < mod.count; ++i) progDelegate.createObject(flick.contentItem, {"source": mod.get(i), "y": index * 50}) 
       } 
      } 
     } 
     Flickable { 
      id: flick 
      height: parent.height 
      width: parent.width - list.width 
      contentWidth: 1200 
      contentHeight: contentItem.childrenRect.height 
      clip: true 
      flickableDirection: Flickable.HorizontalFlick 
      contentY: list.contentY 
     } 
    } 
} 
+0

Спасибо! Много! Два вопроса: 1) в вашем примере прокрутка по вертикали работает только в столбце канала, а не в области программ, в то время как вы, похоже, указываете иначе («Таким образом, вы можете прокручивать по вертикали от обоих и только прокручивать по горизонтали программы».) , 2) любая идея о том, что использование памяти имеет практически пустое значение, с большим содержаниемWidth/HeightN –

+0

1 - Я написал пример, как через 20 минут после написания текста перед ним. В то время я решил, что было бы более «здорово» иметь вертикальную прокрутку в каналах. Вы можете сделать двустороннюю привязку, удалить существующие и использовать 'onContentYChanged' обоих представлений для синхронизации другого. 2 - это не занимает никакой памяти, это «воображаемая область», просто логика, это не похоже на растровое изображение с каждым заполненным пикселем. – dtech

+0

Понял! Спасибо, что помогли мне. –

Смежные вопросы