2017-07-11 3 views
0

Ich bin dabei, eine auf QtWidgets basierende Anwendung auf QtQuick2 zu portieren.QFormLayout entspricht in QtQuick2?

Ich versuche herauszufinden, welche QtQuick-Layout-Elemente ich verwenden sollte.

Ich stecke bei QFormLayout. Ich kann einfach kein Äquivalent finden. Das Beste, was ich finden konnte, ist ein GridLayout, aber ich möchte, dass die Labels automatisch generiert werden (like in QFormLayout).

QHBoxLayout wandelt in RowLayout
QVBoxLayout umwandelt ColumnLayout
QGridLayout umwandelt GridLayout
QFormLayout zu umwandelt ???

+0

Da ich mit dem 'QFormLayout' nicht vertraut bin, können Sie bitte erklären, was Sie zu tun versuchen und wie Sie es verwenden möchten? – derM

+0

Ich versuche, einen sehr einfachen Dialog mit mehreren Eingabefeldern zu implementieren. Jedes Eingabefeld sollte sein eigenes Label haben.Wenn ein Benutzer versehentlich auf das Label anstelle des Eingabeelements klickt, möchte ich, dass das Eingabeelement fokussiert wird (Buddy-Funktionalität). Ich denke, es wäre besser, wenn ich nicht selbst Labels erstellen müsste und ein FormLayout das tun müsste (wie in QtWidgets). Ich wollte nur den kanonischsten Weg gehen. –

Antwort

1

Wenn Sie mit dem GridLayout zufrieden sind, nur die automatische Etiketten Generation fehlt, können Sie sich einige kleine Hilfsklasse erstellen, in dem Sie die Label einkapseln und eine Eigenschaft für die Kontrolle halten.

// FormControl.qml

import QtQuick 2.0 
import QtQuick.Controls 2.0 

Item { 
    id: root 
    property alias label: myLabel 

    Label { 
     id: myLabel 
     parent: root.parent 

     Layout.fillHeight: true 
     Layout.fillWidth: true 

     verticalAlignment: Qt.AlignVCenter 

     MouseArea { 
      anchors.fill: parent 
      onClicked: root.control.forceActiveFocus() 
     } 
    } 

    property Item control 

    Row { 
     id: content 
     parent: myLabel.parent // parent it to myLabel.parent, to make sure, that one is added first. 
     children: [control] 
    } 
} 

Die Verwendung ist einfach:

import QtQuick 2.7 
import QtQuick.Layouts 1.1 
import QtQuick.Controls 2.0 

ApplicationWindow { 
    id: myWindow 
    visible: true 
    width: 600 
    height: 600 
    color: 'white' 

    GridLayout { 
     columns: 2 

     FormControl { 
      label.text: 'test1' 
      control: ComboBox { 
       model: ['hello', 'world', 'and', 'bye'] 
      } 
     } 

     FormControl { 
      label.text: 'Text' 
      control: TextField { 
      } 
     } 

     FormControl { 
      label.text: 'Something Long' 
      control: TextField { 

      } 
     } 
    } 
} 

Sie könnten die control weglassen, wenn Sie es das default property Item control in FormControl.qml erklären. Dann könnten Sie jedoch versehentlich mehrere Steuerelemente hinzufügen, wobei das erste verloren geht.

Ich nutze die , um von der impliziten Höhe und Breite zu profitieren, aber Sie könnten auch eine Item verwenden und die Breite und Höhe auf childrenRect.width/height setzen. Ich bin mir jedoch nicht sicher, ob das robust ist.

0

Soweit ich weiß, gibt es keine Entsprechung für QFormLayout in QML.

Sie müssen die Komponente selbst mit einer Repeater und GridLayout definieren.

können Sie einige Details finden Sie hier: Populate GridLayout with Repeater

Beispiel einer FormLayout.qml:

import QtQuick 2.0 
import QtQuick.Window 2.0 
import QtQuick.Layouts 1.2 
import QtQuick.Controls 2.0 

GridLayout { 
    id: grid 

    // Emitted when text has changed 
    signal inputTextChanged(int index, string text) 

    columns: 2 
    rowSpacing: 5 
    columnSpacing: 5 

    property var labels: [] 

    Repeater { 
     model: grid.labels 
     Text { 
      Layout.row: index 
      Layout.column: 0 
      Layout.preferredWidth: 100 
      Layout.preferredHeight: 100 
      text: modelData 
      verticalAlignment: Text.AlignVCenter 
     } 
    } 

    Repeater { 
     model: grid.labels 
     TextField { 
      Layout.row: index 
      Layout.column: 1 
      Layout.preferredWidth: 100 
      Layout.preferredHeight: 40 
      onTextChanged: inputTextChanged(index,text) 
     } 
    } 
} 

main.qml:

import QtQuick 2.5 
import QtQuick.Controls 2.0 
import QtQuick.Layouts 1.2 

ApplicationWindow { 
    visible: true 
    width: 640 
    height: 480 
    title: qsTr("Hello World") 


    FormLayout { 
     anchors { 
      fill: parent 
      margins: 5 
     } 

     labels: ["label1","label2"] 
     onInputTextChanged: console.log(index + "/" + text) 
    } 
} 

labelsany model that qml accept sein kann (JS-Array, ListModel, oder AbstractItemModel von C++).

qformlayout

+0

Kann ich irgendwie ein Array für die Elemente selbst verwenden? Sie unterscheiden sich von Zeile zu Zeile und ich muss auch Eigenschaften für sie festlegen. Kann ich irgendwie die Buddy-Funktionalität aktivieren, in der Qt weiß, welches Label zu welchem ​​Artikel gehört? –

+0

Ja, Sie können, @derM Lösung ist es für Sie passender. Was die Buddy-Funktionalität betrifft, glaube ich nicht, dass es ein Äquivalent gibt. Aber ich bezweifle, dass du es in QML brauchst! – Blabdouze

+0

Sie können, zumindest setzen Sie es aktiv konzentrieren. Fügen Sie dem Text in Ihrem ersten Repeater einen 'MouseArea' hinzu. 'onClicked: secondRepeater.itemAt (Index) .forceActiveFocus()'. Es öffnet das PopUp für 'ComboBox's jedoch nicht. – derM