QML TabButton positioning in Column - qt

I'm trying to position TabButtons in TabBar vertically. But the position of each TabButton is somewhere I didn't intend. It seems like they're anchored by root Item.
Item {
id: element
width:800; height:800
Rectangle {
id: container
anchors.fill:parent
color:"red"
Rectangle {
id: subContainer
anchors.left:parent.left
anchors.leftMargin: 100
anchors.top:parent.top
anchors.topMargin: 100
width:200
height:450
TabBar {
id: tabBar
anchors.top:parent.top;
anchors.bottom:parent.bottom
anchors.left:parent.left;
anchors.leftMargin:100
width:120
Column {
id: column
anchors.fill:subContainer //
TabButton {
id:tab1
anchors.top:tabBar.top; anchors.left:tabBar.left
width: tabBar.width; height:tabBar.height/3;
}
TabButton {
id:tab2
anchors.top:tab1.bottom; anchors.left:tabBar.left
width: tabBar.width; height:tabBar.height/3;
}
TabButton {
id:tab3
anchors.top:tab2.bottom; anchors.left:tabBar.left
width: tabBar.width; height:tabBar.height/3;
}
} // End of Column
} // End of TabBar
}
StackLayout { // this stack seems to be working as I've intended
id: stack
anchors.top:parent.top;
anchors.bottom: parent.bottom;
anchors.left : bar.right;
anchors.right:parent.right
Rectangle {
id: homeTab
color:"yellow"
width: 300; height:300
}
Rectangle {
id: discoverTab
color:"skyblue"
width: 300; height:300
}
Rectangle {
id: activityTab
color:"lightgray"
width: 300; height:300
}
}
}
}
And in designer of QT creator, I can see like below screen capture. tab1 is positioned ignoring it's anchors properties. Could anybody let me know what I'm misunderstanding.

Your anchors are not set properly, You also don't need that column:
Item {
id: element
width:800; height:800
Rectangle {
id: container
anchors.fill:parent
color:"red"
Rectangle {
id: subContainer
anchors.left:parent.left
anchors.leftMargin: 100
anchors.top:parent.top
anchors.topMargin: 100
width:200
height:450
TabBar {
id: tabBar
anchors.top:parent.top;
anchors.bottom:parent.bottom
anchors.left:parent.left;
width:120
TabButton {
id:tab1
anchors.top:parent.top; anchors.left:parent.left
width: tabBar.width; height:tabBar.height/3;
}
TabButton {
id:tab2
anchors.top:tab1.bottom; anchors.left:parent.left
width: tabBar.width; height:tabBar.height/3;
}
TabButton {
id:tab3
anchors.top:tab2.bottom; anchors.left:parent.left
width: tabBar.width; height:tabBar.height/3;
}
} // End of TabBar
}
StackLayout {
id: stack
anchors.top:parent.top;
anchors.bottom: parent.bottom;
anchors.left : subContainer.right;
anchors.right:parent.right
Rectangle {
id: homeTab
color:"yellow"
width: 300; height:300
}
Rectangle {
id: discoverTab
color:"skyblue"
width: 300; height:300
}
Rectangle {
id: activityTab
color:"lightgray"
width: 300; height:300
}
}
}
}

Related

Text over the Swipe, how to fix?

I have ListView with items like this:
And I want use swipe. But when I add SwipeDelegate I get this:
How I can make swipe elements over the text? I try use z properties, but with z my swipe not animated when opened and I can't close it.
Here my code:
//SomePage.qml:
import QtQuick 2.12
import QtQuick.Controls 2.12
ScrollView {
ListView {
id: someListView
model: SomeItems {}
delegate: SwipeDelegate {
width: someListView.width
Row {
leftPadding: 5
width: parent.width
Image {
id: someImg
height: 38
source: myImage
width: height
}
Column {
leftPadding: 5
width: parent.width - someImg.width - 10
// Name
Text {
id: someName
text: myCount.toString() + " × " + myName
}
// Number
Text {
id: someNumber
text: myNumber.toLocaleString(Qt.locale("ru-RU"), "f", 0)
anchors.right: parent.right
font.pixelSize: 12
rightPadding: 5
}
}
}
swipe.right: Row {
anchors.right: parent.right
height: parent.height
// Delete button
Label {
text: "\ue800"
color: "black"
font.family: fontFontello.name
height: parent.height
padding: 12
verticalAlignment: Label.AlignVCenter
width: this.height
background: Rectangle {
color: "lightblue"
height: parent.height
width: parent.width
MouseArea {
anchors.fill: parent
onClicked: someListView.model.remove(index)
}
}
}
// Hide button
Label {
text: "\ue80a"
color: "black"
font.family: fontFontello.name
height: parent.height
padding: 12
verticalAlignment: Label.AlignVCenter
width: this.height
background: Rectangle {
color: "lightgray"
MouseArea {
anchors.fill: parent
onClicked: {
...
swipe.close()
}
}
}
}
}
}
}
}
The problem is you're adding your text/image on top of the default contentItem instead of inside it. It will look correct if you add your Row to contentItem, like this:
delegate: SwipeDelegate {
contentItem: Row {
...
}
}

QML - Why does TabBar's implicitWidth depend on binding inner TabButton's width to its implicitWidth?

Why in the following code implicitWidth of TabBar changes when I comment out width: implicitWidth in TabButtons? Why does the fact that I am setting width of a component to be equal to its implicitWidth change the implicitWidth?
Also, I thought width was set to implicitWidth by default anyways when width is not explicitly set. So I don't understand why doing width: implicitWidth would have any effects. Here is the code:
Item {
id: root
height: 480
width: 640
RowLayout {
anchors.fill: parent
TabBar {
id: bar
Layout.fillHeight: true
implicitWidth: Math.max(homeTabButton.implicitWidth, discoverTabButton.implicitWidth, activityTabButton.implicitWidth)
background: Rectangle {
color: "yellow"
}
contentItem: ListView {
model: bar.contentModel
}
TabButton {
id: homeTabButton
width: implicitWidth // I cannot comment this out
text: qsTr("Home")
}
TabButton {
id: discoverTabButton
width: implicitWidth // I cannot comment this out
text: qsTr("Discover")
}
TabButton {
id: activityTabButton
width: implicitWidth // I cannot comment this out
text: qsTr("Activity")
}
}
StackLayout {
Layout.fillWidth: true
Layout.fillHeight: true
currentIndex: bar.currentIndex
Pane {
id: homeTab
background: Rectangle {
color: "blue"
}
}
Pane {
id: discoverTab
background: Rectangle {
color: "red"
}
}
Pane {
id: activityTab
background: Rectangle {
color: "green"
}
}
}
}
}
U have assigned an implicit width before
implicitWidth: Math.max(homeTabButton.implicitWidth, discoverTabButton.implicitWidth, activityTabButton.implicitWidth)
that's why when u comment width in tabButton it taking width as 0.
use
width: Math.max(homeTabButton.implicitWidth, discoverTabButton.implicitWidth, activityTabButton.implicitWidth)
in your code and comment that width in tabButton ans see.

Drag and Drop in ListView

I am trying to drag and drop a ListView row and I am having trouble at the drag stage. Below code doesn't drag anything and name column is not aligned properly. I don't want to specify a size for ListView and I want it to get its size from its content Row with id row. It should be able to because text has size coming from its font size and Rectangle has set width. ListView can get wider as needed to show the name part.
import QtQuick 2.11
import QtQuick.Layouts 1.11
ListView {
id: root
height: scrollview.viewport.height
model: listModel
delegate: dragDelegate
Component {
id: dragDelegate
MouseArea {
id: dragArea
anchors { left: parent.left; right: parent.right }
height: content.height
drag.target: pressed ? content : undefined
drag.axis: Drag.XAndYAxis
Rectangle {
id: content
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
height: row.implicitHeight
border.width: 1
border.color: "lightsteelblue"
color: "green"
radius: 2
states: State {
when: dragArea.pressed
ParentChange { target: content; parent: root }
AnchorChanges {
target: content
anchors { horizontalCenter: undefined; verticalCenter: undefined }
}
}
Row {
id: row
Text {
text: name
font.pointSize: 15
}
Rectangle {
height: parent.height
width: 40
color: hexColor
}
}
}
}
}
ListModel {
id: listModel
ListElement {
name: "first-name"
hexColor: "red"
}
ListElement {
name: "second-name"
hexColor: "green"
}
}
}

Change Text Color of the selected item in a ListView

Let me start by saying that I am pretty new to QML.
I have a ListView (with model and delegate), it works fine in my model but I would like to change the color (currently color: skin.gray) of the selected item to something else when the item is the currentIndex-item.
ListView {
id: menuBody_listview
width: parent.width
height: parent.height
currentIndex: 0
clip: true
highlight: highlighter
highlightFollowsCurrentItem: true
Behavior on opacity {
NumberAnimation { property: "opacity"; duration: 300; easing.type: Easing.InOutQuad }
}
anchors {
top: menuHeader_listview.bottom
bottom: parent.bottom
}
model: ListModel {
ListElement {
itemIconLeft: 'images/icons/menu/pause.png'
itemText: "Cancel"
itemIconRight: 'images/icons/menu/take-me-home.png'
}
ListElement {
itemIconLeft: 'images/icons/menu/pause.png'
itemText: "Mute"
itemIconRight: 'images/nill.png'
}
ListElement {
itemIconLeft: 'images/icons/menu/repeat.png'
itemText: "Repeate"
itemIconRight: 'images/nill.png'
}
}
delegate: MenuBodyItem {
width: menuBody_listview.width
anchors.horizontalCenter: parent.horizontalCenter
iconLeft: itemIconLeft
message: itemText
iconRight: itemIconRight
}
}
Following is the code for the item which is being populated, ManuBodyItem.qml.
Item {
width: 100
height: 50
property alias iconLeft: menuitem_icon_start.source
property alias message: menuitem_text.text
property alias iconRight: menuitem_icon_end.source
RowLayout {
spacing: 20
anchors.fill: parent
Image {
id: menuitem_icon_start
fillMode: Image.PreserveAspectCrop
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
}
Text {
id: menuitem_text
anchors {
left: menuitem_icon_start.right
verticalCenter: parent.verticalCenter
verticalCenterOffset: -2
leftMargin: 20
}
color: skin.gray
font {
family: "TBD"
}
}
Image {
id: menuitem_icon_end
fillMode: Image.PreserveAspectCrop
source: iconRight
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
}
}
}
Use ListView's isCurrentItem attached property:
Text {
id: menuitem_text
anchors {
left: menuitem_icon_start.right
verticalCenter: parent.verticalCenter
verticalCenterOffset: -2
leftMargin: 20
}
color: itemDelegate.ListView.isCurrentItem ? "red" : skin.gray
font {
family: "TBD"
}
}
Note that you have to give your root delegate item an ID in order to qualify the expression above:
Item {
id: itemDelegate
RowLayout {
// ...
}
// ...
}
You can see the same approach used in the example I linked to.
From your example:
color: skin.gray is used for the Text element which will change the color of the text and not it's background viz. i understood you want.
You can use a Rectangle element here which can act as a background component to set the background color.
So instead of Item root element in the delegate you can use Rectangle. So MenuBodyItem.qml will look as
Rectangle {
width: 100
height: 50
...
}
Now to set background color to the Rectangle if it is current one you can use ListView.isCurrentItem to check.
So,
Rectangle {
color: ListView.isCurrentItem ? "cyan" : "lightblue"
width: 100
height: 50
}
and now finally you will have to set the clicked item as the current one which can be done in the MouseArea of the Delegate Item
delegate: MenuBodyItem {
width: menuBody_listview.width
anchors.horizontalCenter: parent.horizontalCenter
iconLeft: itemIconLeft
message: itemText
iconRight: itemIconRight
MouseArea {
anchors.fill: parent
onClicked: menuBody_listview.currentIndex = index
}
}

Need responsive height for DropDown List in QML for ComboBox?

I am creating a custom combobox model in which i need to assign a height of a dropDown list in responsive value. It is on length of items at present so unable to reduce or increase its height as per screen resolution. Here is my code :
Rectangle {
width:150;
height: 60;
Rectangle {
id:comboBox
property variant items: ["Item 1", "Item 2", "Item 3"]
property alias selectedItem: chosenItemText.text;
property alias selectedIndex: listView.currentIndex;
signal comboClicked;
width: 100;
height: 30;
z: 100;
smooth:true;
Rectangle {
id:chosenItem
radius:4;
width:parent.width;
height:comboBox.height;
color: "lightsteelblue"
smooth:true;
Text {
anchors.top: parent.top;
anchors.left: parent.left;
anchors.margins: 8;
id:chosenItemText
text:comboBox.items[0];
font.family: "Arial"
font.pointSize: 14;
smooth:true
}
MouseArea {
anchors.fill: parent;
onClicked: {
comboBox.state = comboBox.state==="dropDown"?"":"dropDown"
}
}
}
Rectangle {
id:dropDown
width:comboBox.width;
height:0;
clip:true;
radius:4;
anchors.top: chosenItem.bottom;
anchors.margins: 2;
color: "lightgray"
ListView {
id:listView
height:500;
model: comboBox.items
currentIndex: 0
delegate: Item{
width:comboBox.width;
height: comboBox.height;
Text {
text: modelData
anchors.top: parent.top;
anchors.left: parent.left;
anchors.margins: 5;
}
MouseArea {
anchors.fill: parent;
onClicked: {
comboBox.state = ""
var prevSelection = chosenItemText.text
chosenItemText.text = modelData
if(chosenItemText.text != prevSelection){
comboBox.comboClicked();
}
listView.currentIndex = index;
}
}
}
}
}
Component {
id: highlight
Rectangle {
width:comboBox.width;
height:comboBox.height;
color: "red";
radius: 4
}
}
states: State {
name: "dropDown";
PropertyChanges { target: dropDown; height:30*comboBox.items.length }
}
transitions: Transition {
NumberAnimation { target: dropDown; properties: "height"; easing.type: Easing.OutExpo; duration: 1000 }
}
}
}
Please suggest me some solution.

Resources