2017-07-11 103 views
0

我正在將基於QtWidgets的應用程序移植到QtQuick2中。與QtQuick2等效的QFormLayout?

我想弄清楚我應該使用哪些QtQuick佈局項目。我在QFormLayout卡住了。我根本找不到相應的東西。我能找到的最好的是一個GridLayout,但我希望自動生成標籤(like in QFormLayout)。

QHBoxLayout轉換爲RowLayout
QVBoxLayout轉換爲ColumnLayout
QGridLayout轉換爲GridLayout
QFormLayout轉換爲???

+0

由於我對'QFormLayout'不熟悉,請您解釋一下,您正在嘗試做什麼以及您計劃如何使用它? – derM

+0

我試圖實現一個非常簡單的對話框與多個輸入字段。每個輸入字段都應該有自己的標籤。如果用戶不小心點擊標籤而不是輸入項目,我希望輸入項目被聚焦(好友功能)。我認爲這會更好如果我不需要自己創建標籤並讓FormLayout執行此操作(與QtWidgets中的相同)。我只是想用最規範的方式。 –

回答

1

如果你滿意的GridLayout,唯一缺少的自動標籤生成,你可以創建自己的一些小的輔助類,在其中封裝Label並保持該控件的屬性。

// 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] 
    } 
} 

的用法很簡單:

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 { 

      } 
     } 
    } 
} 

,當你在FormControl.qml聲明它的default property Item control你可能會忽略control。然後,然而你可能會無意中添加多個控件,其中第一個將會丟失。

我使用受益於隱含的高度和寬度,但您也可以使用Item並將寬度和高度設置爲childrenRect.width/height。不過,我不確定這是否穩健。

0

據我所知,在QML中沒有QFormLayout的等價物。

您必須使用RepeaterGridLayout自己定義組件。

你可以在這裏找到一些細節:一個 FormLayout.qml的Populate GridLayout with Repeater

例子:

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) 
    } 
} 

labels可以any model that qml accept (JS數組,ListModel,或來自C++的AbstractItemModel)。

qformlayout

+0

我可以以某種方式爲項目本身使用數組嗎?它們不同於行與行,我也需要在它們上設置屬性。我可以以某種方式啓用好友功能,讓Qt知道哪個標籤屬於哪個項目? –

+0

是的,你可以看到@derM解決方案,它更適合你。至於夥伴的功能,我不認爲有相同的功能。但我懷疑你會在QML中需要它! – Blabdouze

+0

您至少可以設置焦點。在第一個轉發器的「文本」中添加一個'MouseArea'。 'onClicked:secondRepeater.itemAt(index).forceActiveFocus()'。雖然它不會打開'ComboBox'的PopUp。 – derM