PDA

View Full Version : issue loading component with model



jfinn88
10th January 2017, 20:33
I have splitView with two rectangles that hold ListViews with two model sets one for items and one for sub-items, I would like the user to press a plus button to display a textArea in the listView to add in new items or sub-Items but keep battling undefined warnings for qml ids (parent/sibling relationships) I'm using state mechanism and a loader/component in the listView its self..... issue with refrencing qml id's being undefined...



//---Rect to hold checkList---//
Rectangle {
id: checkListView_rect
z: 1
width: 1350
height: 430
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 0
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 230
border{
color: "black"
width: 3
}
layer.enabled: true
layer.effect: DropShadow {
horizontalOffset: 8
verticalOffset: 8
radius: 8.0
samples: 16
color: "#80000000"
source: checkListView_rect
}
//---SplitView for Items & Sub-Items---//
SplitView {
id: checklist_splitView
anchors.margins: 3
anchors.fill:parent
orientation: Qt.Horizontal
//---Items Rectangle---//
Rectangle {
id: itemsRectangle
width: parent.width * 0.5
height: parent.height
Layout.minimumWidth: 350
color: "steelblue"
ScrollView {
id: item_scrollView
anchors.fill:parent
flickableItem.interactive: true
style: cmd_scrollbar_style
GroupBox {
title: qsTr("Items")
anchors.top: parent.top
//---Row layout for editting buttons---//
Row{
id: addRemove_ItemRow
anchors.horizontalCenter: parent.horizontalCenter
height: 50
//---Adds New Item---//
Button {
id: add_item
width: 48
height: 48
anchors.verticalCenter: parent.verticalCenter
onClicked: {
item_scrollView.state = "addItem"
}
style: XToolBtnStyle {
bkg_image:"add.png"
bkg_title: qsTr("Add")
image_size: 32
text_size: 9
text_color: "white"
}
}
//---Delete Item----//
Button {
id: delete_item
width: 48
height: 48
action: deleteItem_action
anchors.verticalCenter: parent.verticalCenter
style: XToolBtnStyle {
bkg_image:"remove.png"
bkg_title: qsTr("Remove")
image_size: 32
text_size: 9
text_color: "white"
}
}
}
}
//---Items listview---//
ListView {
id: itemsListView
anchors.fill: parent
anchors.topMargin: 75
interactive: true
model: itemModel
currentIndex: 0
focus: true
delegate: Item {
id: item_delegate
width: itemsListView.width
height: 50
TextArea {
id: itemTextArea
width: parent.width
height: 50
activeFocusOnPress: true
backgroundVisible: false
readOnly: true
wrapMode: Text.WordWrap
text: qsTr(itemRole + " " + textRole)
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
item_delegate.state = "editItem"
}
Keys.onEnterPressed: {
//itemsListView.currentIndex = index;
//checklistUI.updateItems(index);
//checklist_edit.currentItemIndex = index;
}
}
}
states: [
State {
name: "editItem"
PropertyChanges {target: itemTextArea; readOnly: false}
},
State {
name: "addItem"
PropertyChanges{target: addItem_loader; sourceComponent: addItem_textField_component}
AnchorChanges{target: addItemTextArea; anchors { top: itemTextArea.bottom}}
//PropertyChanges {target: addItemTextArea; readOnly: false}
}
]

//---TextField for Adding new Items---//
Component {
id: addItem_textField_component
TextField {
id: addItemTextArea
activeFocusOnPress: true
readOnly: false
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
//itemsListView.currentIndex = index;
//checklistUI.updateSubitems(index);
//checklist_edit.currentItemIndex = index;
}
}
}
}

//---Displays TextField for adding new Item---//
Loader {
id: addItem_loader
property string filename: ""
width: parent.width
height: 50
sourceComponent: null
anchors.top: parent.bottom
anchors.centerIn: parent
z: 2
}
}


had to chop up my code a bunch to get it to fit


//---SubItem Rectangle---//
Rectangle {
id: subitemsRectangle
width: parent.width * 0.5
height: parent.height
Layout.minimumWidth: 350
color: "lightgrey"
ScrollView {
id: subItem_scrollView
anchors.fill:parent
flickableItem.interactive: true
style: cmd_scrollbar_style
GroupBox {
title: qsTr("Sub-Items")
anchors.top: parent.top
//---Row layout for editting buttons---//
Row{
id: addRemove_subItemRow
anchors.horizontalCenter: parent.horizontalCenter
height: 50
//---Adds New SubItem---//
Button {
id: add_subItem
width: 48
height: 48
anchors.verticalCenter: parent.verticalCenter
onClicked: {
subItem_scrollView.state = "addSubItem"
}
style: XToolBtnStyle {
bkg_image:"add.png"
bkg_title: qsTr("Add")
image_size: 32
text_size: 9
text_color: "white"
}
}
//---Deletes SubItem---//
Button {
id: delete_subItem
width: 48
height: 48
anchors.verticalCenter: parent.verticalCenter
action: deleteSubItem_action
style: XToolBtnStyle {
bkg_image:"remove.png"
bkg_title: qsTr("Remove")
image_size: 32
text_size: 9
text_color: "white"
}
}
}
}
//---Sub Item ListView---//
ListView {
id: subItemsListView
anchors.fill: parent
anchors.topMargin: 75
model: subitemModel
interactive: true
currentIndex: 0
delegate: Item {
id: subItem_delegate
width: subItemsListView.width
height: 100
TextArea {
id: subItemTextArea
width: parent.width
height: 100
backgroundVisible: false
readOnly: true
wrapMode: Text.WordWrap
text: qsTr(subitemRole + " " + subitemTextRole)
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
subItem_delegate.state = "editSubItem"
}
Keys.onEnterPressed: {
//subItemsListView.currentIndex = index;
//checklistUI.updateSubitems(index);
//checklist_edit.subItemIndex = index;
}
}
}
states: [
State {
name: "editSubItem"
PropertyChanges {target: subItemTextArea; readOnly: false}
},
State {
name: "addSubItem"
PropertyChanges{target: addSubItem_loader; sourceComponent: addSubItem_textField_component;}
AnchorChanges{target: addSubItemTextArea; anchors { top: subItemTextArea.bottom}}
//PropertyChanges {target: addSubItemTextArea; readOnly: false}
}
]

//---TextField for Adding new Sub-Items---//
Component {
id: addSubItem_textField_component
TextField {
id: addSubItemTextArea
activeFocusOnPress: true
readOnly: false
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
itemsListView.currentIndex = index;
checklistUI.updateSubitems(index);
checklist_edit.currentItemIndex = index;
}
}
}
}

//---Displays TextField for adding new Sub-Item---//
Loader {
id: addSubItem_loader
property string filename: ""
width: parent.width
height: 50
anchors.top: parent.bottom
anchors.centerIn: parent
sourceComponent: null
z: 2
}
}

anda_skoa
11th January 2017, 10:38
I had a cursory look, one thing that is problematic is the attempt to reference an id from inside a Component.

A Component is a bit like a separate file, id values from within it are not "visible" to the place where the component is being used.
After all, there could be many instances of the component.

So instead of referring to e.g. "addItemTextArea" you would need to refer to the loader's "item".

Cheers,
_

jfinn88
11th January 2017, 15:57
Thats what I thought but wasnt sure thanks for the help

jfinn88
11th January 2017, 19:11
anda_skoa,

I understand why referencing the id of the component won't work and you confirmed my suppositions on it. However instead of referencing the id of the textField in the component you suggest to use the loader item Property? its a read only property so was wondering if you could enlighten me on how the item property of the loader would work... as the documentation has a one sentence description on it...

do I use the name of the loader (id) and then use the item to find out what top level qml component is loaded at the time ? addSubItem_loader.item how do I access the textField in that component using the item property I'm not sure how do this



ScrollView {
id: item_scrollView
anchors.fill:parent
flickableItem.interactive: true
style: cmd_scrollbar_style
GroupBox {
title: qsTr("Items")
anchors.top: parent.top
//---Row layout for editting buttons---//
Row{
id: addRemove_ItemRow
anchors.horizontalCenter: parent.horizontalCenter
height: 50
//---Adds New Item---//
Button {
id: add_item
width: 48
height: 48
anchors.verticalCenter: parent.verticalCenter
onClicked: {
addItem_loader.item.state = "addItem"
item_delegate.state = "addItem"
}
style: XToolBtnStyle {
bkg_image:"add.png"
bkg_title: qsTr("Add")
image_size: 32
text_size: 9
text_color: "white"
}
}
//---Delete Item----//
Button {
id: delete_item
width: 48
height: 48
action: deleteItem_action
anchors.verticalCenter: parent.verticalCenter
style: XToolBtnStyle {
bkg_image:"remove.png"
bkg_title: qsTr("Remove")
image_size: 32
text_size: 9
text_color: "white"
}
}
//---Move Items Position in List---//
Button {
id: moveItemUP
width: 50
height: 45
Image {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
source: "up_arrow.png"
sourceSize.width: 24
sourceSize.height: 24
Text {
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: "Item"
font.pixelSize: 9
}
}
onClicked: checklistUI.moveItemUp(itemsListView.currentIndex)
}
Button {
id: moveItemDown
width: 50
height: 45
enabled: false
Image {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
source: "down_arrow.png"
sourceSize.width: 24
sourceSize.height: 24
Text {
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
text: "Item"
font.pixelSize: 9
}
}
//onClicked: checklistUI.moveItemDown(itemsListView.currentInde x)
}
}
}
//---Items listview---//
ListView {
id: itemsListView
anchors.fill: parent
anchors.topMargin: 75
interactive: true
model: itemModel
currentIndex: 0
focus: true
delegate: item_component
highlight: item_highlight
}
}




//---Item Delegate Component---//
Component{
id: item_component
Item {
id: item_delegate
width: itemsListView.width
height: 50
TextArea {
id: item_text
width: parent.width
//height: calcHeight(item_metrics.boundingRect.height + 25)
//contentHeight: 50
height: 50
backgroundVisible: false
readOnly: true
wrapMode: Text.WordWrap
text: item_metrics.text
activeFocusOnPress: true

//---JavaScript function calulates Text Field height for display---//
function calcHeight(text_height){
if(text_height < 350)
return 350
else if(text_height > 550)
return 550
else
return text_height
}

//---Changes height of displayed text based off amount of text to display---//
//onItemChanged: {
//item_metrics.text = textRole
//item_text.height = calcHeight(item_metrics.boundingRect.height + 25)
//}

//---Sets properties & formatting for text item below---//
TextMetrics{
id:item_metrics
font.pointSize: 10
text: qsTr(itemRole + " " + textRole)
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
addItem_loader.state = "editItem"
itemsListView.currentIndex = index;
//---updates sub-item model for display---//
checklistUI.updateSubitems(index);
checklist_edit.currentItemIndex = index;
}
Component.onCompleted: {
addItem_loader.state = "editItem"
}

Keys.onReturnPressed: {
//checklistUI.updateItems(index);
}
}

//---Displays TextField for adding new Item---//
Loader {
id: addItem_loader
property string filename: ""
width: parent.width
height: 50
sourceComponent: null
anchors.top: parent.bottom
anchors.centerIn: parent
z: 2
//item: addItem_textField

states: [
State {
name: "editItem"
PropertyChanges {target: item_text; readOnly: false}
},
State {
name: "addItem"
PropertyChanges{target: addItem_loader; sourceComponent: addItem_textField}
AnchorChanges{target: addItemTextArea; anchors { top: item_text.bottom}}
}
]

//---TextField for Adding new Items---//
Component {
id: addItem_textField
TextField {
id: addItemTextArea
activeFocusOnPress: true
readOnly: false
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
//itemsListView.currentIndex = index;
//checklistUI.updateSubitems(index);
//checklist_edit.currentItemIndex = index;
}
}
}
}
}
}
}

anda_skoa
12th January 2017, 09:26
The Loader's item can be used a bit like and id, i.e. to refere to the loaded item

For example, in a non-loader situation you might have this


Text {
text: input.text
}
TextField {
id: input
}


When using a Loader for the "input" it would look like this


Text {
text: loader.item ? loader.item.text : ""
}
Loader {
id: loader
}

I.e. instead of "input" this now refers to "loader.item". With a check for "item" actually existing before accessing it as it will not always be present.

Btw, in your case, where your Loader component is simple, you could avoid using the loader and just set the item visible/invisible as needed.

Cheers,
_