how to load child1.qml page on to main.qml page calling from another_child.qml page - qt

In my MyHeader.qml cannot load the MyChild2.qml. How to load child qml page on to mmain.qml page calling from another child qml page as shown below.
TestProject Folder
qml Folder
Main.qml
MyChild1.qml
mainui Folder
MyHeader.qml
MyChild2.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
// Main.qml
ApplicationWindow {
id: rootApp
Loader {
id: loaderPage
anchors.fill: parent
}
MyChild1 {
}
}
// MyChild1.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Page {
id: myItem1
anchors.fill: parent
MyHeader {
anchors.top: parent.top
}
}
// MyChild2.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Page {
id: myItem2
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "#000000"
}
}
// MyHeader.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Rectangle {
id: myHeader
width: parent.width
height: dp(30)
color: "lightblue"
Text {
id: loadQML
text: "Load QML"
color: "#000000"
font.pixelSize: dp(20)
MouseArea {
anchors.fill: parent
onClicked: {
myItem1.visible = false
loaderPage.source = "MyChild2.qml"
loaderPage.Top
}
}
}
}
Using the Loader and Connection I am getting Cannot assign to non-existent property "onPageChanged"
import QtQuick 2.10
import "mainui"
ApplicationWindow {
id: rootApp
signal pageChanged(int page);
Loader {
id:rootLoader
anchors.fill: parent
source: "mainui/Page1.qml"
Connections {
target: rootLoader.item
onPageChanged: {
switch(page)
{
case 1: rootLoader.source = "mainui/Page1.qml"; break;
case 2: rootLoader.source = "mainui/Page2.qml"; break;
}
}
}
}
} // APP

Due to scope limitation of Loader you cannot access items outside it. But you can notify the Loader to do some action. In the example below there are 2 components define a signal. The Loader connects this signal to a handler:
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
id: win
width: 400
height: 400
title: "Test"
visible: true
Component {
id: page1
Rectangle {
signal pageChanged(int page);
anchors.fill: parent
color: "orange"
Text {
anchors.centerIn: parent
text: "PAGE 1\nClick to change"
horizontalAlignment: Text.AlignHCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
pageChanged(2);
}
}
}
}
Component {
id: page2
Rectangle {
signal pageChanged(int page);
anchors.fill: parent
color: "lightblue"
Text {
anchors.centerIn: parent
text: "PAGE 2\nClick to change"
horizontalAlignment: Text.AlignHCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
pageChanged(1);
}
}
}
}
Loader {
id: loader
anchors.fill: parent
sourceComponent: page1
Connections {
target: loader.item
onPageChanged: {
switch(page)
{
case 1: loader.sourceComponent = page1; break;
case 2: loader.sourceComponent = page2; break;
}
}
}
}
}

Related

How to declare a property of type EventHandler (slot?) in Custom Component and assign function for that in its usage

For my Custom window, shown in the answer, I've created a Component named PathButton
import QtQuick 2.0
import QtQuick.Shapes 1.12
Item {
property alias pathData: svg.path
width: 24
height: 24
Shape {
ShapePath {
fillColor: "black"
PathSvg {
id: svg
path: pathData
}
}
}
}
and used it to minimize, maximize and close the window like this:
RowLayout{
Layout.preferredWidth: 100
anchors.right: title.right
PathButton{
pathData: ViewModel.minimizeIcon
MouseArea{
anchors.fill: parent
onClicked: mainWindow.showMinimized()
}
}
PathButton{
pathData: ViewModel.maximizeIcon
MouseArea{
anchors.fill: parent
//this doesn't restore the window to its Normal state, showMaximized() is called always
onClicked: mainWindow.Maximized? mainWindow.showNormal() : mainWindow.showMaximized()
}
}
PathButton{
pathData: ViewModel.closeIcon
MouseArea{
anchors.fill: parent
onClicked: mainWindow.close()
}
}
}
in all those I've a MouseArea. What I want is to have that MouseArea in my Custom Component and declare a property of type eventhandler/signal/slot and assign that handler for onClicked like this:
import QtQuick 2.0
import QtQuick.Shapes 1.12
Item {
property alias pathData: svg.path
property alias handler: mouse.onClicked
width: 24
height: 24
Shape {
ShapePath {
fillColor: "black"
PathSvg {
id: svg
path: pathData
}
}
}
MouseArea{
id: mouse
anchors.fill: parent
onClicked: handler
}
}
and in its usage I want to assign the relevant function like this:
PathButton{
pathData: ViewModel.minimizeIcon
handler: mainWindow.showMinimized()
}
EDIT
Here's what I've in PathButton.qml:
import QtQuick 2.0
import QtQuick.Shapes 1.12
Item {
id: root
property alias pathData: svg.path
signal onClicked()
width: 24
height: 24
Shape {
ShapePath {
fillColor: "black"
PathSvg {
id: svg
path: pathData
}
}
}
MouseArea{
anchors.fill: parent
onClicked: root.onClicked()
}
}
and in main.qml I get that error and when I hit run with that error, in Application Output I get another error:
I think what you're looking for is simply a signal:
// PathButton.qml
Item {
id: root
signal clicked()
...
MouseArea {
onClicked: root.clicked()
}
}
Then you would use it like this:
PathButton {
onClicked: mainWindow.showMinimized()
}

Pass value from child QtQuck QML to main QML

I have to pass some values from child QML open with component to main QML and use them to do something in main QML.
This is my two QML files:
I have mail.qml like this:
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.3
ApplicationWindow {
id: applicationWindow
property string selected_contact_account_str: String()
/* Contacts */
function createContacts() {
var component = Qt.createComponent("ContactList.qml");
console.log("Component Status:", component.status, component.errorString());
var window = component.createObject(applicationWindow, {"x": 0, "y": 0});
window.showFullScreen();
}
Icon {
id: contacts
anchors.top: parent.top
anchors.topMargin: 60
anchors.left: parent.left
anchors.leftMargin: 20
iconsize: 96
iconsource: "content/contacts_icon.png"
iconname: "Contacts"
fontsize: 14
MouseArea {
anchors.fill: parent
onClicked: createContacts()
}
}
/* End Contacts */
}
And an ContactList.qml with Button:
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Window 2.2
ApplicationWindow {
id: contactsList
Item {
Item {
id: appContainer
anchors.fill: parent
anchors.centerIn: parent
Button {
id: contact_select
text: qsTr("Select")
onClicked: {
// I want to pass value from here to main.qml
// store in selected_contact_account_str
// So I can use it in mail.qml
}
}
}
}
How can I do?
you can use signal and slot to do it.
In
ApplicationWindow
id: contactsList
signal sendmessage(var message)
.
.
.
onClicked: {
contactsList.sendmessage("test");
}
then in first file
function createContacts() {
window.sendmessage.connect(handleMessage)
}
function handleMessage(message){
}

TableView QML Type onClicked event

I am currently using a TableView in my QML file. I would like to know which cell the user clicked.. There is a post here: https://forum.qt.io/topic/84284/tableview-onclicked-slot/2 which shows the onClicked code in the QML file. However, when i tried on my code it says invalid property name. My QML file code is:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import TransactionHistoryTableModel 1.0
import tech.siotgov.DataManager 1.0
import "../../components" as Components
import "../../utils/httpRequest.js" as HttpRequest
Rectangle {
id: root
objectName: "TransactionHistory"
color: "white"
property string pageTitle: "Transaction History"
ColumnLayout {
id: home
anchors.leftMargin: parent.width * 0.05
anchors.rightMargin: parent.width * 0.05
anchors.fill: parent
anchors.horizontalCenter: parent.horizontalCenter
Components.PageTitle {
title: pageTitle
}
Rectangle {
id: transactionHistoryDisplay
color: "white"
Layout.fillWidth: true
Layout.preferredHeight: parent.height - 100
Components.Table {
model: _transactionHistoryTableModelAPI
columnWidths: [0.4, 0.6]
onClicked: {
console.log(" click ")
console.log(color_string)
}
}
}
Item { //spacer
Layout.fillWidth: true
Layout.fillHeight: true
Rectangle {
anchors.fill: parent
color: "white"
}
}
}
Component.onCompleted: {
const locationId = DataManager.currentLocation.locationId;
const d = new Date()
d.setTime(d.getTime() - d.getTimezoneOffset()*60*1000);
const datetimeStamp = d.toISOString().split('.')[0]
_transactionHistoryTableModelAPI.resetTable(locationId);
HttpRequest.query(
"query { transactionsByLocation(fromDateTime:\"2019-01-01T07:54:34\", toDateTime:\"" + datetimeStamp + "\", location:" + locationId + ") { transactionId, datetime, items { transactionItemId }, transactionType {name}, location_1{locationName}, location_2{locationName} } }",
res => {
_transactionHistoryTableModelAPI.updateTable(res.data.transactionsByLocation);
})
}
}
The Table.qml file is:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
TableView {
anchors.fill: parent
clip: true
property var columnWidths: [0.5, 0.5] // as fractions of parent width
// preferably overwrite this when using
columnWidthProvider: function (column) { return Math.max(parent.width * columnWidths[column], 1) }
delegate: Rectangle {
implicitHeight: text.implicitHeight
border.color: "#dddddd"
color: (heading==true)?"#dddddd":"white"
Text {
id: text
text: tabledata
width: parent.width
wrapMode: Text.Wrap
padding: 5
}
}
}
In a view you must set the MouseArea in the delegate and expose it through a signal from the root of the component:
Table.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
TableView {
id: root
anchors.fill: parent
clip: true
signal clicked(int row, int column) // <---
property var columnWidths: [0.5, 0.5] // as fractions of parent width
// preferably overwrite this when using
columnWidthProvider: function (column) { return Math.max(parent.width * columnWidths[column], 1) }
delegate: Rectangle {
implicitHeight: text.implicitHeight
border.color: "#dddddd"
color: heading ? "#dddddd" : "white"
Text {
id: text
text: tabledata
width: parent.width
wrapMode: Text.Wrap
padding: 5
}
MouseArea{
anchors.fill: parent
onClicked: root.clicked(model.row, model.column) // <---
}
}
}
*.qml
// ...
Components.Table {
model: _transactionHistoryTableModelAPI
columnWidths: [0.4, 0.6]
onClicked: console.log(row, column)
}
// ...

Adding TabButton dynamically to TabBar in QML

I am trying to add a tabButton to TabBar dynamically on pressing a button but i have spent a lot of time searching but i am not getting how to add, below is the code which i am working on :
MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Item
{
property int BtnWidth:0
property int BtnHeight:0
property string BtnText: ""
property bool isChecked : false
TabButton
{
id:tabBtn
text:BtnText
width:BtnWidth
height:BtnHeight
}
}
MainForm.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Rectangle
{
Button
{
id:button
width:100
height:100
anchors.top:parent.top
text:qStr("Add")
onClicked{
//How to add logic here to add tab in below tabBar.
}
}
TabBar
{
id:tabBar
anchors.top:button.bottom
width:500
height:500
}
}
Example:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
width: 360
height: 630
visible: true
header: TabBar {
id: tabBar
}
Component {
id: tabButton
TabButton { }
}
Button {
text: "Add"
anchors.centerIn: parent
onClicked: {
var tab = tabButton.createObject(tabBar, {text: "Tab " + tabBar.count})
tabBar.addItem(tab)
}
}
}
You need to have something like a Component that is a TabButton. Your file MyTabButton.qml won't result in a TabButton, but instead an Item containing a TabButton, but with this, your TabBar does not know what to do.
So your file will need to have TabButton as root element
//MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
TabButton
{
id: tabBtn
// customize as you like
}
Then you create a Component of this in your file where you want to use it. (e.g. main.qml)
import QtQuick 2.4
import QtQuick.Controls 2.0
ApplicationWindow {
width: 800
height: 600
visible: true
TabBar {
id: tabBar
width: 800
height: 50
}
// The component is like a factory for MyTabButtons now.
// Use myTabButton.createObject(parent, jsobject-with-property-assignments) to create instances.
Component {
id: myTabButton
MyTabButton {
/// EDIT ACCORDING TO YOUR COMMENTS ***
Connections {
target: tabBar
onCurrentIndexChanged: doSomething()
}
/// EDIT OVER
}
}
Button {
anchors.centerIn: parent
// Create a object out of the component, and add it to the container
onClicked: tabBar.addItem(myTabButton.createObject(tabBar /*, { object to set properties }*/))
}
}
TabBar inherits Container, which has addItem().
Try it in Window
Row {
anchors.fill: parent
TabBar {
id: tabBar
currentIndex: 0
width: parent.width - addButton.width
TabButton { text: "TabButton" }
}
Component {
id: tabButton
TabButton { text: "TabButton" }
}
Button {
id: addButton
text: "+"
flat: true
onClicked: {
tabBar.addItem(tabButton.createObject(tabBar))
console.log("added:", tabBar.itemAt(tabBar.count - 1))
}
}
}

How to use mouseclick area from loaded Form in qml?

below is my code snippet where i'm loading qml ui using dynamic object creation method now i have to implement mousearea which reside in loaded file, can anyone help me to do this
Qt.createQmlObject(" import QtQuick 2.0
Loader {
id: pageLoader
source: '/HomeScreenForm.ui.qml'
anchors.fill: parent
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.bottomMargin: parent
anchors.topMargin: parent
}
", rectangle7)
Create custom item contains MouseArea. To make the area accessible from outside you can use alias, for example:
MyItem.qml
import QtQuick 2.7
Rectangle {
id: root
color: "yellow"
property alias area: mouseArea
MouseArea {
id: mouseArea
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: "Click me!"
}
}
And then you can create it dynamically:
import QtQuick 2.7
import QtQuick.Window 2.0
Window {
id: mainWindow
width: 600
height: 600
visible: true
Component.onCompleted: {
var component = Qt.createComponent("MyItem.qml");
if (component.status === Component.Ready) {
var obj = component.createObject(mainWindow);
obj.width = 200;
obj.height = 200;
obj.anchors.centerIn = mainWindow.contentItem;
obj.area.onPressed.connect(
function(mouse){
console.log("pressed at (", mouse.x,",",mouse.y,")")
});
}
}
}
Another way is using Connections, as #derM already noticed.

Resources