2015-08-30 4 views
1

Я хотел бы концентрировались элементы в QML ListView и поэтому я добавил следующий код моего ListView:Попытка центрирования элементов программно в ListView

import QtQuick 2.0 
import QtMultimedia 5.5 
import QtQuick.Controls 1.3 
import QtQuick.Extras 1.4 
import QtQuick.Layouts 1.2 
import QtQuick.Window 2.2 
import QtTest 1.1 

Rectangle { 
    id: ueKeypad 

    width: ueMainColumnLayout.implicitWidth+2*radius 
    height: ueMainColumnLayout.implicitHeight+2*radius 

    color: "grey" 

    radius: 8 

    border.color: "#99c6f0" 
    border.width: 4 

    ColumnLayout { 
     id: ueMainColumnLayout 

     anchors.fill: parent 
     anchors.margins: radius 

     spacing: 4 

     RowLayout { 
      id: ueTextLayout 

      Text { 
       id: ueStaffLoginText 

       text: qsTr("Staff Login") 

       verticalAlignment: Text.AlignVCenter 
       horizontalAlignment: Text.AlignHCenter 

       font.family: "Padauk" 
       textFormat: Text.RichText 

       font.pointSize: 16 
       font.bold: true 

       color: ueKeypad.border.color 

       Layout.fillWidth: true 
      } // ueStaffLoginText 
     } // ueTextLayout 

     RowLayout { 
      id: uePeopleViewLayout 

      ListView { 
       id: uePeopleView 

       keyNavigationWraps: true 

       spacing: 4 

       antialiasing: true 

       model: uePeopleModel 

       Layout.fillWidth: true 
       Layout.fillHeight: false 

       //Layout.minimumWidth: 64 
       Layout.minimumHeight: 64 
       //Layout.preferredWidth: 96 
       Layout.preferredHeight: 96 
       //Layout.maximumWidth: 128 
       Layout.maximumHeight: 128 

       orientation: ListView.Horizontal 
       layoutDirection: Qt.LeftToRight 

       snapMode: ListView.SnapToItem 

       highlightRangeMode: ListView.ApplyRange 

       Component.onCompleted: { 
        var newIndex=(count%2==0)?(count/2):(Math.round(count/2)); 

        positionViewAtIndex(newIndex, ListView.Center); 
        currentIndex=newIndex; 
        print(newIndex) 
       } // onCompleted - center items 

       delegate: Rectangle { 
         id: uePersonDelegate 

         width: 32 
         height: 32 

         ColumnLayout { 
          id: uePersonDelegateMainLayout 

          anchors.fill: parent 
          anchors.margins: radius 

          RowLayout { 
           id: uePersonDelegateImageLayout 

           Image { 
            id: uePersonImage 

            antialiasing: true 

            fillMode: Image.PreserveAspectFit 

            source: "image://uePeopleModel/"+model.ueRoleImage 
           } // uePersonImage 
          } // uePersonDelegateImageLayout 

          RowLayout { 
           id: uePersonDelegateNameLayout 

           Text { 
            id: ueTextPersonName 

            color: "#ffffff" 

            text: model.ueRoleName 

            font.bold: true 
            font.pixelSize: 16 

            verticalAlignment: Text.AlignVCenter 
            horizontalAlignment: Text.AlignHCenter 
           } // ueTextPersonName 
          } // uePersonDelegateNameLayout 
         } // uePersonDelegateMainLayout 
        } // uePersonDelegate 

       add: Transition { 
        NumberAnimation { 
         property: "opacity"; 
         from: 0; 
         to: 1.0; 
         duration: 100 
        } // NumberAnimation 

        NumberAnimation { 
         property: "scale"; 
         from: 0; 
         to: 1.0; 
         duration: 100 
        } // NumberAnimation 
       } // Transition 

       displaced: Transition { 
        NumberAnimation { 
         properties: "x,y"; 
         duration: 100; 
         easing.type: Easing.OutBounce 
        } // NumberAnimation 
       } // Transition 
      } // uePeopleView 
     } // uePeopleViewLayout 

     RowLayout { 
      id: ueTumblerLayout 

      Tumbler { 
       id: ueLoginKeypadTumbler 

       Layout.fillWidth: true 
       Layout.fillHeight: false 

       height: 100 

       antialiasing: true 

       TumblerColumn { 
        id: ueNumericTumblerColumnDigit1000 

        model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
       } // ueNumericTumblerColumnDigit1000 

       TumblerColumn { 
        id: ueNumericTumblerColumnDigit100 

        model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
       } // ueNumericTumblerColumnDigit100 

       TumblerColumn { 
        id: ueNumericTumblerColumnDigit10 

        model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
       } // ueNumericTumblerColumnDigit10 

       TumblerColumn { 
        id: ueNumericTumblerColumnDigit1 

        model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
       } // ueNumericTumblerColumnDigit1 
      } // ueLoginKeypadTumbler 
     } // ueTumblerLayout 

     RowLayout { 
      id: ueButtonsLayout 

      Button { 
       id: ueButtonLogin 

       Layout.fillWidth: true 

       text: qsTr("Login") 
      } // ueButtonLogin 

      Button { 
       id: ueButtonClear 

       Layout.fillWidth: true 

       text: qsTr("Clear") 
      } // ueButtonClear 

      Button { 
       id: ueButtonQuitApp 

       Layout.fillWidth: true 

       text: qsTr("Quit") 
      } // ueButtonQuitApp 
     } // ueButtonsLayout 
    } // ueMainColumnLayout 

    states: [ 
     State { 
      name: "ueStateLoginOk" 

      PropertyChanges { 
       target: ueKeypad 
       border.color: "#00ff00" 
      } 

      PropertyChanges { 
       target: ueLoginText 
       color: "#00ff00" 
      } 
     }, // ueStateLoginOk 

     State { 
      name: "ueStateLoginOkFailed" 

      PropertyChanges { 
       target: ueKeypad 
       border.color: "#ff0000" 
      } 

      PropertyChanges { 
       target: ueLoginText 
       color: "#ff0000" 
      } 
     } // ueStateLoginOkFailed 
    ] // states 
} // ueKeypad 

Теперь print(newIndex) заявление печатает правильное значение 3 (в моем случае, так как на данный момент у меня есть 5 предметов), и я хотел бы, чтобы 3-й предмет находился в центре ListView и других двух предметах с левой и правой сторон. Это возможно? И вне сферы действия этого вопроса, почему Transition также не работает, взято из примера?

Я также установил highlightRangeMode: ListView.ApplyRange, взятый из комментария.

Вот скриншот проблемы:

QML Items not centered

ответ

4

Проблема здесь заключается в том, что вы пытаетесь поместить ListView делегатов в соответствии с вашими потребностями. Это неправильно, так как ListView (как и все другие виды) предназначен для вас, в соответствии с размером ListView. ListView будет всегда использовать все доступное пространство, в результате чего делегаты все расположены слева, как вы пережили.

Вместо того чтобы форсировать поведение делегатов, вы должны ограничить размер ListView и поместить его в центр. Затем вы можете использовать highlightRangeMode с preferredHighlightBegin и preferredHighlightEnd от this answer, чтобы убедиться, что выбранный вами Item находится в центре списка. Кроме того, используя StrictlyEnforceRange, вы можете заставить выбранный Item оставаться всегда в центре, что приведет к тому, что ИМО сможет лучше выбрать нужный Item.

Вот пример реализации этого подхода. Размеры жестко закодированы для простоты, но могут быть легко параметризованы. Как сказано, я пошел немного дальше, установив политику выделения. Надеюсь, поможет.

import QtQuick 2.4 
import QtQuick.Window 2.2 
import QtQuick.Layouts 1.1 

Window { 
    id: win 
    width: 300 
    height: 300 
    visible: true 

    ColumnLayout { 
     anchors.fill: parent 

     Rectangle { 
      Layout.fillWidth: true 
      Layout.fillHeight: true 
      color: "blue" 
     } 

     ListView { 
      Layout.alignment: Qt.AlignCenter 
      Layout.minimumWidth: 30 * 5 + 40 
      Layout.preferredHeight: 50 
      clip: true 
      spacing: 15 
      model: 10 
      orientation: ListView.Horizontal 
      delegate: Item { 
       width: 30 
       height: 50 
       Rectangle{ 
        anchors.centerIn: parent 
        color: parent.ListView.isCurrentItem ? "red" : "steelblue" 
        width: 30 
        height: 30 
        Text { 
         text: index 
         anchors.centerIn: parent 
        } 
        scale: parent.ListView.isCurrentItem ? 1.5 : 1 
        Behavior on scale { NumberAnimation { duration: 200 } } 
       } 
      } 
      preferredHighlightBegin: width/2 - 15 
      preferredHighlightEnd: width/2 + 15 
      highlightRangeMode: ListView.StrictlyEnforceRange 
      Component.onCompleted: currentIndex = count/2 
     } 

     Rectangle { 
      Layout.fillWidth: true 
      Layout.fillHeight: true 
      color: "yellow" 
     } 
    } 
} 

enter image description here

+0

должен это может также работать для вертикального 'ListView'? – KernelPanic

+0

@KernelPanic он должен быть адаптирован для учета высоты вместо ширины, но есть основные этапы. Я думаю, что вы должны найти что-то подобное на SO (или, по крайней мере, я помню, чтобы дать ответ для вертикального ввода ... но может быть и неправильным). – BaCaRoZzo

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