I can not find a way to use a loader to fill a tab within a tabview. The loader works fine when it is outside of the TabView (ie if I remove the multi line comment characters at the top of mainTrial.qml and the Loader plus Connections are at the top. But if I move the Loader in line as a child of a tab, I get an error "Cannot assign multiple values to a singular property. Neither can I address the Loader that is outside of TabView using menuLoader.source or column1.menuLoader.source or other variants. Here is the main file. (the other two files that define the signals are included so that you can see that the signals work). What am I doing wrong?
Edit: (Good ole law of permutations and combinations) I discovered that if I make the Connections declaration, a child of the Loader that is on the tab, the problem goes away. I will have but one "value" assigned on the tab - that being the Loader and now I can load a qml item per tab.
//mainTrial
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Item {
id: trial
width: 360
height: 360
ColumnLayout {
id: column1
spacing:150
Item {Layout.fillHeight: true}
TabView {
id: tabPages
Tab {
id: welcomePage
title: "Welcome"
// /*
Loader{
id: menuLoader
source: "mainTrial1.qml"
anchors.top: parent.top
Connections {
id: menuConnection
ignoreUnknownSignals: true
target: menuLoader.item
onMainTrial3: {
menuLoader.source = "mainTrial3.qml"
console.log("originated from " + origin)
}
onMainTrial1: {
menuLoader.source = "mainTrial1.qml"
console.log("originated from " + origin)
}
}
}
}
Tab {
id: statusPage
title: "Status"
}
}
}
}
// mainTrial1 (with one signal definition)
This file defines one of the signals used to load the next qml object. I included it here so that you can see that the signal works).
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Item {
id: page1
property string origin: "Hello"
signal mainTrial3(string origin)
ColumnLayout {
spacing: 15
Rectangle {
width: 100
height: 62
color: "red"
MouseArea {
anchors.fill: parent
onClicked: {
mainTrial3("origin = from MouseArea")
}
}
}
Button {
text: "Sorting and scanning"
onClicked: {
mainTrial3(origin = "from Button")
}
}
}
}
//mainTrial3 (with the other signal definition)
This file defines the other signal used to reload the previous qml object. I included it here so that you can see that both signals work when one clicks on the rectangles).
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Item {
id: page3
property string origin: "Hello"
signal mainTrial1(string origin)
GridLayout {
columnSpacing: 5
rowSpacing: 5
columns: 1
Rectangle {
width: 100
height: 62
color: "blue"
MouseArea{
anchors.fill: parent
onClicked: {
mainTrial1(origin = "from MouseArea1")
}
}
}
Rectangle {
width: 100
height: 62
color: "blue"
MouseArea{
anchors.fill: parent
onClicked: {
mainTrial1("from MouseArea2")
}
}
}
}
}
Ok so I took your code, used a bit, and customized the rest to load a single tab to make talking around it a bit easier. It's not exactly what you posted but it should show you how to:
With this you should have solid foundation to further customize and add in two, three, etc... tabs and dynamically change them based upon the signals in my example.
Importantly, Tab
itself is a Loader
so there is no need to define a inner Loader
. Next I'm not entirely experienced with QML yet (QWidget is more my thing) but the Connections
that you are using seemed to cause some problems, I'm not sure their entirely needed, so I removed them from my example.
In my example I just load a single QML file in a tab and send a signal when you click on either the blue rectangle or the red rectangle inside the tab that was just loaded.
You'll be able to see the print out in the console. I've left a comment in the signal handler where you could then change the source
of the Tab
and dynamically load the next Tab
.
Enjoy!
TabViewTest.qml
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Item {
id: tabViewTest
width: 360
height: 360
TabView {
id: tabView
width: parent.width
height: parent.height
Tab {
title: "Welcome"
id: dynamicTab
anchors.top: parent.top
// [1] Specify the source URL to load the content.
source: "RectanglesTab.qml"
// [2] Define a signal within the Tab that will
// be connected to the 'contentsClicked' signal
// in each tab QML file.
signal tabContentsClicked( string rectColor )
// [3] Implement the signal handler.
onTabContentsClicked: {
console.log( "Clicked on a", rectColor, "rectangle." )
// [4] Now that the user has clicked somewhere within the tab
// you could optionally the source or sourceComponent here like
// the comment below.
//
// Just make sure it also has a signal called 'contentsClicked'
//
// dynamicTab.source = "someOtherTab.qml"
}
onLoaded: {
console.debug( "Loaded", source );
// [4] Here's the key action, connect the signal
// 'contentsClicked' to our signal
// 'tabContentsClicked' from the loaded item
// i.e. RectanglesTab.qml
dynamicTab.item.contentsClicked.connect(tabContentsClicked)
}
}
Tab {
id: statusTab
title: "Status"
}
}
}
RectanglesTab.qml
import QtQuick 2.0
import QtQuick.Layouts 1.1
Rectangle {
id: rectanglesTab
width: parent.width
height: parent.height
color: "black"
signal contentsClicked( string rectColor )
GridLayout {
width: parent.width
height: parent.height
columnSpacing: 5
rowSpacing: 5
columns: 1
Rectangle {
width: parent.width
height: 120
color: "blue"
MouseArea{
anchors.fill: parent
onClicked: {
contentsClicked( "blue" )
}
}
}
Rectangle {
width: parent.width
height: 120
color: "red"
MouseArea{
anchors.fill: parent
onClicked: {
contentsClicked( "red" )
}
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With