2015-06-02 17 views
6

Ho progettato un layout in QML per saperne di più sulle sue funzioni e ho alcune domande sulle "Best Practice" nella progettazione di tale layout. Qui è:Come progettare un layout fluido a più livelli in QML

enter image description here

È essenzialmente un ColumnLayout consisteva di tre RowLayout s, ognuno con alcune rettangolo s. La dimensione di ogni riga e Rettangolo dovrebbe essere calcolare quali:

  • Prima fila: Altezza = 40%, Larghezza = 100%
    • Rosso Rettangolo riempiendo l'intera area
  • Seconda fila : Altezza = 20%, Larghezza = 100%
    • scuro-verde rettangolo: Altezza = 100%, Larghezza = 20%,
    • verde chiaro rettangolo: Altezza = 100%, Larghezza = 80%
  • Terza riga: Altezza = 40%, Larghezza = 100%
    • blu scuro rettangolo: Altezza = 100%, Larghezza = 40%,
    • rettangolo blu: Altezza = 100%, Larghezza = 20%
    • Light-rettangolo blu: Altezza = 100%, Larghezza = 40%

Il QML che ho si avvicinò con sta lavorando ed è nel seguente. Ho alcune domande su di esso:

  1. ho esposto le percentuali di larghezza e altezza utilizzando Layout.preferredHeight: x * parent.height modello. Altre opzioni hanno causato alcuni problemi (ad esempio preferredHeight ha causato avvisi di loop vincolanti). Il mio approccio è corretto ed efficiente?
  2. Come trucco, ho impostato Layout.fillWidth: true per il primo elemento della riga 2 e della riga 3, che non ha senso per me, ma funziona. Se imposto la loro larghezza in percentuale (ad esempio Layout.preferredWidth: 0.2 * parent.width), la loro riga verrà ridotta alla larghezza 0. Si tratta di un comportamento previsto? C'è qualche soluzione migliore?
  3. Avete suggerimenti sui layout? Sono sulla buona strada?

Ecco il mio codice QML per il layout:

ApplicationWindow { 
    x: 500 
    y: 100 
    width: 250 
    height: 150 
    visible: true 

    ColumnLayout { 
     anchors.fill: parent 
     spacing: 0 
     RowLayout { 
      spacing: 0 
      Layout.preferredHeight: 0.4*parent.height 
      Layout.fillHeight: false 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.fillWidth: true 
       color: "red" 
      } 
     } 
     RowLayout { 
      spacing: 0 
      Layout.preferredHeight: 0.2*parent.height 
      Layout.fillHeight: false 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.fillWidth: true 
       color: "darkGreen" 
      } 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 0.8*parent.width 
       color: "lightGreen" 
      } 
     } 
     RowLayout { 
      spacing: 0 
      Layout.preferredHeight: 0.4*parent.height 
      Layout.fillHeight: false 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.fillWidth: true 
       color: "darkBlue" 
      } 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 0.2*parent.width 
       color: "blue" 
      } 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 0.4*parent.width 
       color: "lightBlue" 
      } 
     } 
    } 
} 

Aggiornamento:

Il mio approccio sembra essere più hacky di quanto mi aspettassi:

  1. Mettere Testo elementi come bambini in questo layout genera binding ing ciclo avvertimenti come:

QML QQuickLayoutAttached: ciclo Binding rilevato per la proprietà "preferredWidth"

Se un involucro di testo all'interno di un rettangolo gli avvertimenti scompaiono.

  1. La spaziatura : 0 sembra svolgere un ruolo importante. Omettendo causerà avvertimenti di loop vincolanti.

Mentre il mio approccio alla progettazione del layout fluido in QML funziona, presenta alcuni problemi gravi e potrebbe non rientrare nelle "migliori pratiche".

+0

Puoi mostrare dove nella documentazione indica il ** Layout.preferredXXX **? Non sembra una proprietà QML e non ho potuto trovare nella documentazione di Qt5.4. – danielfranca

+0

Ecco la documentazione per la proprietà che sto usando: http://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html. A proposito, sto ancora ricevendo _Binding loop rilevato per la proprietà "preferredHeight" _ per layout più complessi, il che significa che il mio approccio ha certamente alcuni difetti. – Isaac

+2

Stavo ricevendo _binging loop_ warnings su un altro layout che è stato creato utilizzando questo approccio. Apparentemente la spaziatura **: 0 ** ha un ruolo nell'evitare questo avvertimento. Impostandolo su zero, alcuni avvisi spariscono. – Isaac

risposta

2

QtQuick.Layout non fornisce alcun miglioramento reale rispetto al sistema di ancoraggio classico. Vorrei raccomandare di evitarli. Puoi avere molto più controllo sul tuo layout usando le ancore.

Qui è lo stesso disegno esatto senza QtQuick.Layout:

ApplicationWindow { 
    x: 500 
    y: 100 
    width: 250 
    height: 150 
    visible: true 

    Column { 
     anchors.fill: parent 

     Row { 
      anchors.left: parent.left 
      anchors.right: parent.right 
      height: 0.4 * parent.height 

      Rectangle { 
       anchors.top: parent.top 
       anchors.bottom: parent.bottom 
       width: parent.width 
       color: "red" 
      } 
     } 

     Row { 
      anchors.left: parent.left 
      anchors.right: parent.right 
      height: 0.2 * parent.height 

      Rectangle { 
       anchors.top: parent.top 
       anchors.bottom: parent.bottom 
       width: 0.2 * parent.width 
       color: "darkGreen" 
      } 

      Rectangle { 
       anchors.top: parent.top 
       anchors.bottom: parent.bottom 
       width: 0.8 * parent.width 
       color: "lightGreen" 
      } 
     } 

     Row { 
      anchors.left: parent.left 
      anchors.right: parent.right 
      height: 0.4 * parent.height 

      Rectangle { 
       anchors.top: parent.top 
       anchors.bottom: parent.bottom 
       width: 0.4 * parent.width 
       color: "darkBlue" 
      } 
      Rectangle { 
       anchors.top: parent.top 
       anchors.bottom: parent.bottom 
       width: 0.2 * parent.width 
       color: "blue" 
      } 
      Rectangle { 
       anchors.top: parent.top 
       anchors.bottom: parent.bottom 
       width: 0.4 * parent.width 
       color: "lightBlue" 
      } 
     } 
    } 
} 

Finora non ho mai incontrato qualsiasi disegno che era impossibile fare a meno QtQuick.Layout.

+0

Bel approccio! Avete risorse che utilizzano questo approccio per più esempi? A proposito, vedi qualche differenza tra 'width: parent.width' vs.' anchors.left: parent.left; anchors.right: parent.right'? – Isaac

+1

@isaac: puoi guardare l'esempio qml fornito con qt. l'uso di ancore imposta anche x e y contemporaneamente, fornisce anche margini più intuitivi rispetto al calcolo della larghezza e dell'altezza – BlueMagma

1

È vietato (e non necessario) provare e fare riferimento alla larghezza e all'altezza del genitore dagli articoli all'interno del layout.

Quando fillWidth (o fillHeight) è impostato true, poi elementi sono allocati spazio in proporzione alla loro specifica preferredWidth (o preferredHeight).

Pertanto, il modo corretto per creare il layout è il seguente. Ho modificato l'aspetto solo per mostrare che la spaziatura e Text possono anche essere impostati liberamente come desiderato. Nessun loop vincolante.

ApplicationWindow { 
    x: 500 
    y: 100 
    width: 250 
    height: 150 
    visible: true 

    ColumnLayout { 
     anchors.fill: parent 
     spacing: 5 
     RowLayout { 
      spacing: 5 
      Layout.preferredHeight: 40 
      Layout.fillHeight: true 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.fillWidth: true 
       color: "red" 
      } 
     } 
     RowLayout { 
      spacing: 5 
      Layout.preferredHeight: 20 
      Layout.fillHeight: true 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 20 
       Layout.fillWidth: true 
       color: "darkGreen" 
      } 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 80 
       Layout.fillWidth: true 
       color: "lightGreen" 
      } 
     } 
     RowLayout { 
      spacing: 5 
      Layout.preferredHeight: 40 
      Layout.fillHeight: true 
      Text { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 40 
       Layout.fillWidth: true 
       color: "darkBlue" 
       text: "hello world!" 
       horizontalAlignment: Text.AlignHCenter 
       verticalAlignment: Text.AlignVCenter 
      } 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 20 
       Layout.fillWidth: true 
       color: "blue" 
      } 
      Rectangle { 
       Layout.fillHeight: true 
       Layout.preferredWidth: 40 
       Layout.fillWidth: true 
       color: "lightBlue" 
      } 
     } 
    } 
}