2015-08-09 14 views
2

Я разрабатываю приложение QML, где у меня есть три основных вида. Мой код выглядит ниже.Адаптируемый пользовательский интерфейс в QML

SplitView{ 
    ListView{ 
     id: firstView 
    } 
    ListView{ 
     id: secondView 
    } 
    WebView{ 
     id: thirdView 
    } 
} 

Теперь это работает отлично, но я хотел бы сделать это: когда мое главное окно изменяет размер ниже определенной ширины (500) Я хотел бы показать только один вид, так что при нажатии на делегат показать следующее представление (с возможностью возврата к предыдущему виду). Так, например, нажатие на первом представлении покажет второе представление, и нажатие на втором представлении покажет третье представление. Подход, который я хочу, очень похож на приложение Mail в Windows 10. Кто-нибудь знает, как это можно достичь в QML?

+2

Я не вижу здесь «проблемы», вы вполне можете реализовать этот поток логики в своем QML-интерфейсе. Это может быть достигнуто путем «реализации» ... нет волшебства, которое сделает всю работу за вас, если это то, что вам интересно. – dtech

+0

Qml SplitView не дает возможности показывать только один вид при необходимости и переключаться между ними. Верно, что я могу использовать свойство «visible» и скрывать представления, которые я хочу, но тогда пользовательский интерфейс не может быть анимирован. Это мое беспокойство. – daljit97

+0

Не чувствуйте себя обязанным придерживаться элементов пользовательского интерфейса, у вас есть создание динамических объектов, анимация, состояния и все инструменты, необходимые для достижения вашей цели. – dtech

ответ

3

ОК, я приготовил грубый пример, я не модулировал его намеренно, поэтому вы можете увидеть, как он работает в одном источнике. Кроме того, я не знаю, как это делает почтовое приложение Windows 10, поскольку у меня его нет, но оно все еще достаточно близко к вашему описанию.

Вы начинаете с 3 видов списка в строке размера, чтобы заполнить весь пользовательский интерфейс, но если вы уменьшите размер пользовательского интерфейса до минимума 500, виды увеличатся в размере, чтобы заполнить почти весь ui, и когда вы нажимаете на элемент вида, он переместит вас к следующему виду, и если вы нажмете на предыдущее представление, вы вернетесь к нему.

enter image description here

ApplicationWindow { 
    title: qsTr("Hello World") 
    width: 800 
    height: 300 
    minimumWidth: 500 
    visible: true 

    Item { 
     id: adapt 
     width: parent.width 
     height: parent.height 
     property int sizeUnit: width > 500 ? width/5 : 400 
     property bool isPaged: width == 500 ? true : false 
     onIsPagedChanged: { if (!isPaged) { x = 0; page = 0; } } 
     property int page: 0 

     Behavior on x { NumberAnimation { duration: 250; easing.type: Easing.OutBack } } 

     ListModel { 
      id: mod 
      ListElement { name: "one" } 
      ListElement { name: "two" } 
      ListElement { name: "three" } 
      ListElement { name: "four" } 
      ListElement { name: "five" } 
     } 

     ListView { 
      id: v1 
      width: adapt.sizeUnit 
      height: parent.height 
      model: mod 
      delegate: Rectangle { 
       height: 70 
       width: v1.width 
       color: "red" 
       border.color: "black" 
       Text { anchors.centerIn: parent; text: name } 
       MouseArea { 
        anchors.fill: parent 
        onClicked: { 
         if (adapt.isPaged) { 
          if (adapt.page == 0) { 
           adapt.x = -(v2.x - 100) 
           adapt.page = 1 
          } else { 
           adapt.x = 0 
           adapt.page = 0 
          } 
         } 
        } 
       } 
      } 
     } 

     ListView { 
      id: v2 
      width: adapt.sizeUnit 
      height: parent.height 
      x: adapt.sizeUnit + 10 
      model: mod 
      delegate: Rectangle { 
       height: 70 
       width: v2.width 
       color: "cyan" 
       border.color: "black" 
       Text { anchors.centerIn: parent; text: name } 
       MouseArea { 
        anchors.fill: parent 
        onClicked: { 
         if (adapt.isPaged) { 
          if (adapt.page == 1) { 
           adapt.x = -(v3.x - 100) 
           adapt.page = 2 
          } else { 
           adapt.x = -(v2.x - 100) 
           adapt.page = 1 
          } 
         } 
        } 
       } 
      } 
     } 

     ListView { 
      id: v3 
      width: adapt.isPaged ? adapt.sizeUnit : 3 * adapt.sizeUnit - 20 
      height: parent.height 
      x: v2.x + v2.width + 10 
      model: mod 
      delegate: Rectangle { 
       height: 70 
       width: v3.width 
       color: "yellow" 
       border.color: "black" 
       Text { anchors.centerIn: parent; text: name } 
      } 
     } 
    } 
} 

Этого должно быть достаточно, чтобы ты. Очевидно, что для производства вы можете использовать более элегантную компоновку и наглядность, например, использовать функцию для фактических «скользящих страниц» и якорей, выше это просто для примера.

+0

Да, это очень близко к тому, что я хочу. Думаю, мне, вероятно, придется пожертвовать использованием Qml SplitView. Другая альтернатива (очень простая), с которой я экспериментировал и работает очень хорошо, - это просто использовать элемент QML Loader. Как показано ниже 'Окно { id: window Loader { источник: window.width> 500? Qt.resolvedUrl («SplitView.qml»): Qt.resolvedUrl («SingleView.qml») } } ' – daljit97

+0

@ daljit97 - Я сам никогда не использовал разделенный вид, он существует для сопоставимости со старыми виджетами Qt, ИМО на самом деле не имеет места в стиле QML/«современном» графическом интерфейсе. – dtech

+0

Основная причина, по которой я его использую, заключается в том, что он дает пользователю возможность изменять размеры разных видов. – daljit97

0

Вот моя идея, как решить проблему.

// When width of MainWindow is smaller than 500 stop using SplitView 
property bool useSplitView: (width < 500 ? false : true) 
onUseSplitViewChanged: { 
    if (useSplitView) { 
     firstView.anchors.fill = undefined 
     secondView.anchors.fill = undefined 
     thirdView.anchors.fill = undefined 
     firstView.parent = splitView // splitView is id of SplitView 
     secondView.parent = splitView 
     thirdView.parent = splitView 
    } 
    else { 
     firstView.parent = mainWindow.contentItem // mainWindow is id of MainWindow 
     secondView.parent = mainWindow.contentItem 
     thirdView.parent = mainWindow.contentItem 
     secondView.visible = false 
     thirdView.visible = false 
     firstView.anchors.fill = firstView.parent 
     secondView.anchors.fill = secondView.parent 
     thirdView.anchors.fill = thirdView.parent 
    } 
} 

Когда useSplitView флага изменение, необходимо включить какое-то сенсорная область на взглядах и переключаться между ними по щелчку.

+0

Хорошо, я пробовал ваш подход, но я вижу, что это 'SplitView.qml: 571: TypeError: Type error' несколько раз, и SplitView имеет много ошибок при изменении размера – daljit97

+0

@ daljit97. Возможно, более простым способом было бы просто увеличить один из видов до максимального размера и, чем очистить handleDelegate, чтобы представления не могли быть изменены. –