Adding Items to a layout of a custom component - qt

I have a custom Footer Component which I would like to reuse in different place in my QML App:
Rectangle {
color: "gold"
height: 50
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
}
RowLayout {
anchors.fill: parent
anchors.margins: 10
Button {
text: "quit"
}
}
}
The use of this is easy:
Window {
visible: true
Footer {
}
}
But now I would like to add a "ButtonA" to the RowLayout of my Footer in one view and a "ButtonB" in another view.
How can I achieve that?

See this answer.
You have to declare a default property in Footer.qml:
import QtQuick 2.0
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
Rectangle {
color: "gold"
height: 50
default property alias content: rowLayout.children
anchors {
bottom: parent.bottom
left: parent.left
right: parent.right
}
RowLayout {
id: rowLayout
anchors.fill: parent
anchors.margins: 10
Button {
text: "quit"
}
}
}
This ensures that any items declared as children of Footer instances will be added to its RowLayout.
main.qml:
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
width: 640
height: 480
visible: true
StackView {
id: stackView
anchors.fill: parent
initialItem: viewAComponent
}
Component {
id: viewAComponent
Rectangle {
id: viewA
color: "salmon"
Footer {
id: footerA
Button {
text: "Go to next view"
onClicked: stackView.push(viewBComponent)
}
}
}
}
Component {
id: viewBComponent
Rectangle {
id: viewB
color: "lightblue"
Footer {
id: footerB
Button {
text: "Go to previous view"
onClicked: stackView.pop()
}
}
}
}
}
I used StackView as a convenient way of navigating between the views.

Related

How to update or read TextFiled inside GridLayout which is in TabView

I have below stack of components and I want to read and set value of the TextFiled:
-Rectangle
-----TabView
---------Tab
-----------Rectangle
--------------GridLayout
------------------Rectangle
--------------------TextField <--- I want to access this TextField
I have also a case where I need to access Repeater inside the Tab:
-Rectangle
-----TabView
---------Tab
-----------Rectangle
--------------GridLayout
------------------Repeater
--------------------TextField <--- I want to access this TextField also
I have tried to access it using:
var tab0 = myTabView.getTab(0);
tab0.children[0].text = "Some Text"; // I get Undefined Error
I have tried to access the component using a function inside the Tab:
import QtQuick 2.0
import QtQuick.Controls 2.14 as QQC2
import QtQuick.Layouts 1.14
import QtQuick.Controls 1.4 as QQC1
QQC2.Item {
QQC1.TabView {
QQC1.Tab {
title: "tab1"
function printValue () {
console.log("myTextFld.txt: "+myTextFld.txt); // <-- Getting Error myTextFld undefined.
}
Rectangle {
id: tabHolderRext
color: "blue"
GridLayout {
id: myGrid
model: 7
Repeater {
id: herderRepeater
model: header
delegate: Rectangle {
TextField {
// I want to Access This TextField also
}
}
}
Rectangle {
id: row0Rect
Layout.row: 0
Layout.column: index
TextFiled {
id: myTextFld
text: modelData
}
}
// Rest of the rows
}
}
}
}
}
Item id can be used to access the values from TextField if you have all items in same qml file. If you have different qml files then make use of alias types link to access the values.
Repeater case: The Textfield has to update the underlying modelview --> model first then we can make use of the model's data.
Here is a sample code. I have stacked all item's in the same qml file so that access by id works here.
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
Item {
anchors.fill: parent
anchors.margins: 10
TabView {
anchors.fill: parent
Tab {
title: "TextField"
Item {
anchors.fill: parent
Grid {
spacing: 20
anchors.fill: parent
anchors.margins: 10
Rectangle {
height: 40
width: 150
TextField {
id: inputId
anchors.fill: parent
placeholderText: "enter text"
}
}
Button {
height: 40
width: 150
text: "show txt"
onClicked: labelId.text = inputId.text
}
Rectangle {
height: 40
width: 150
Label {
id: labelId
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
}
Tab {
title: "Repeater"
Item {
anchors.fill: parent
Grid {
spacing: 20
anchors.fill: parent
anchors.margins: 10
columns: 3
ListModel {
id: fruitModel
ListElement { name: "Apple" }
ListElement { name: "Orange" }
ListElement { name: "Banana" }
}
Repeater {
width: parent.width
height: parent.height / 2
model: fruitModel
delegate: Rectangle {
height: 40
width: 150
TextField {
anchors.fill: parent
text: name
onTextChanged: fruitModel.setProperty(index, "name", text) // update model data
}
}
}
Repeater {
width: parent.width
height: parent.height / 2
model: fruitModel
delegate: Rectangle {
height: 40
width: 150
Label {
text: name
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
}
}
}
}
}

Choreography in qml

Is there possible to use choreography animations in qml (in a REUSABLE manner)?
for example in StackView transitions from page1 to page2.
I tried following code, but ParentChange does not work as expected. This code just changes red rectangle's position.
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
StackView {
id: stack
anchors.fill: parent
initialItem: Page {
id: page1
Label {
text: qsTr("First page")
anchors.centerIn: parent
}
Rectangle {
id: rect
width: 50
height: 50
x: 600
y: 100
color: "red"
states: [
State {
when: stack.depth > 1
ParentChange { target: rect; parent: stack.currentItem; x: 100; y: 100; }
}
]
transitions: Transition {
ParentAnimation {
NumberAnimation { properties: "x,y"; duration: 1000 }
}
}
}
MouseArea {
anchors.fill: parent
onClicked: stack.push(page2)
}
}
Component {
id: page2
Page {
background: Rectangle { color: "yellow"; anchors.fill: parent }
Label {
text: qsTr("Second page")
anchors.centerIn: parent
}
}
}
}
Rectangle {
id: back
color: "blue"
width: 50
height: 50
radius: 25
MouseArea {
anchors.fill: parent
onClicked: stack.pop()
}
}
}
but the usage is not limited to StackView. It can be used in many other situations. (just like above link)

How to make the listview align better?

My program consisted of a tabbar and stackLayout. I face a layout problem that the tab button is too close to the head of the listview as shown below. They are horizontally aligned together.
But I want the listview to be under the tab button. I tried adding the topMargin in the listview, but it doesn't have any effect at all. Please help.
The code:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtMultimedia 5.8
import QtQuick.Layouts 1.3
import com.contentplayermod.filemodel 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Tabs")
property int idx: 0
property bool isActive: true
TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("Main")
}
TabButton {
text: qsTr("View")
}
}
StackLayout {
id: stackLayout
height:parent.height
width: parent.width
currentIndex: bar.currentIndex
Item {
id: mainTab
anchors {
topMargin:60
}
width: 500
height:800
ListView {
id: lv
anchors.margins: 50
width: 200; height: 400
highlight: Rectangle { color: "lightsteelblue"; radius: 5 }
focus: true
currentIndex: 0
Component {
id: fileDelegate
Text {
text: fileName
font.pointSize: 20
anchors {
topMargin:60
}
MouseArea{
anchors.fill: parent
}
}
}
model: FileModel{
id: myModel
folder: "c:\\folder"
nameFilters: ["*.mp4","*.jpg"]
}
delegate: fileDelegate
highlightFollowsCurrentItem: true
}
}
Item {
id: viewTab
width: 500
height:800
}
}
}
You can either anchors your stack-top to the bottom of the tab bar like this :
...
StackLayout {
id: stackLayout
height:parent.height - bar.height
anchors.top: bar.bottom
width: parent.width
...
Or much simpler, put everything in a ColumnLayout :
ColumnLayout {
anchors.fill: parent
TabBar {
id: bar
Layout.fillWidth: true
...
}
StackLayout {
id: stackLayout
Layout.fillHeight: true
Layout.fillWidth: true
...
}
}
So you don't have to deal with width and height, and it's more easy to insert new widgets in your window.
You can add spacing to the ColumnLayout to put some space between the TabBar and the content. Or manage this inside the Items displayed by the StackLayout for more flexibility.

Zoom with finger touch on QML and buttom for reset zoom

How to QML with two fingers to zoom in the photo?
I wrote the following code for the Click also I want a button for reset zoom to screen size and i want a buttom for back but for each screen position is different
please help me.
Thank you
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
Window {
id: win
visible: true
width: Screen.width
height: Screen.height
Rectangle {
id: ali
width: win.width
height: win.height
ScrollView {
width: win.width
height: win.height
Rectangle {
id: inspector
Image {
id: visibleImg
x: 0
y: 0
source: "qrc:///pic/1.jpg"
width: inspector.width
height: inspector.height
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_VolumeDown) {
inspector.width=inspector.width+50
inspector.height=inspector.height+50
event.accepted = true;
}
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onClicked:{
if (mouse.button == Qt.LeftButton){
inspector.width=inspector.width+50
inspector.height=inspector.height+50
}
}
}
width: win.width
height: win.height
}
}
Button {
id: button1
x: 1
y: win.width+12
width: 25
height: 25
text: qsTr("+")
onClicked: {
inspector.width=inspector.width+50
inspector.height=inspector.height+50
}
}
Button {
id: button2
x: 1
y: win.width+37
width: 25
height: 25
text: qsTr("-")
onClicked: {
inspector.width=inspector.width-50
inspector.height=inspector.height-50
}
}
anchors.centerIn: ali
}
}
Try with this example :
https://github.com/yekmen/mee500px/blob/master/tags/0.0.5Beta/Mee500px/qml/Mee500px/Tools/ZoomableImage.qml
Work fine !
edit : Update link !
I could change the code as follows:
But only two-finger zoom it down
And the photo can not be moved
Also I'm 10 photos
I want to give everyone the same two buttons display
import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Dialogs 1.2
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
Window {
id: win
visible: true
width: 240
height: 320
title: "aseman-abi"
Rectangle {
id: ali
width: win.width
height: win.height
Rectangle {
id: photoFrame
x: 0
y: 0
width: win.width
height: win.height
color: "#ffffff"
PinchArea {
anchors.fill: parent
pinch.target: photoFrame
pinch.minimumScale: 1
pinch.maximumScale: 5
}
BorderImage {
id: borderImage1
anchors.fill: parent
source: "qrc:///pic/1.jpg"
}
}
Button {
id: button2
x:10
y: win.height-37
width: 50
height:40
text: qsTr("N")
onClicked: {
borderImage1.source="qrc:///pic/2.jpg"
}
}
Button {
id: button3
x: win.width-71
y: win.height-37
width: 50
height: 40
text: qsTr("P")
onClicked: {
borderImage1.source="qrc:///pic/1.jpg"
}
}
}
}

How to switch back between two windows in QML

I Create qml file like this :
main.qml
Item {
width: 200; height: 200
Loader { id: pageLoader }
MouseArea {
anchors.fill: parent
onClicked: pageLoader.source = "Page1.qml"
}
}
I want to back to main page from Page1.qml.
How I can do this Work?
just set the source of pageLoader in Page1 to nothing:
Main Page :
import QtQuick 1.0
Rectangle {
width: 360
height: 360
Text {
anchors.centerIn: parent
text: "Main Page"
}
MouseArea {
anchors.fill: parent
onClicked: {
ld.source="Test.qml"
}
}
Loader{
id:ld;
anchors.fill: parent;
}
}
Test.qml
Rectangle {
width: 100
height: 62
color: "navy";
Text {
anchors.centerIn: parent
text: "Page 1"
}
MouseArea{
anchors.fill: parent;
onClicked: ld.source="";
}
}
Don't you have to instanciate the loader once again in Test.qml to access it via var

Resources