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 {
...
}
}
Related
I have a ListView where the items become visible or not based on whether a header was expanded or not. When the visible property is set to false, there is just blank space in that area. How do I remove the black space in the list so that the next visible item comes in view?
Currently I have set the height:model.count * 50 with 50 being height of each item. I tried subtracting 50 every time an item's visible property is set to false but this just reduces the height of the list overall but the blank space remains.
ListView { id: list
focus: true
anchors.top: header.bottom
anchors.left: parent.left
anchors.right: parent.right
width: parent.width
height:model.count*50
model:hall
Component {
id:comp
Item{
width: parent ? parent.width : 0
height: parent ? parent.height: 0
Column{
id:col1
width: parent.width - 16
height: 25
anchors.centerIn: parent
spacing: 3
Text { id: name
width: parent.width
text: name
elide: Text.ElideMiddle
font: "black"
color: "grey"
}
Row{
width: parent.width
Text { id: file1
width: parent.width * 0.6 - 5
text: "hello"
horizontalAlignment: Text.AlignLeft
elide: Text.ElideMiddle
font: systemFont.TableCellFont
}
Text { id: file2
width: parent.width*0.4 - 3
horizontalAlignment: Text.AlignRight
text: mod
font: systemFont.TableCellFont
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
console.warn("Mouse onClicked")
}
}
}
}
delegate: Item {
width: parent.width;
height: {
if (!cric && expanded)
return 50
else
return 0
}
Loader {
anchors.fill: parent
sourceComponent: comp
height: expanded? 50: 0
readonly property int index:model.index
readonly property string mod: model.mod
visible: !cric && expanded
}
}
Keys.onReturnPressed: {
console.warn("Return pressed")
}
}
The blank space is created because the List item which is hidden by setting visible to false still has its dimensions set. You can update the item height to 0 and the blank space will not be visible. Try this example for reference.
import QtQuick 1.1
Rectangle{
width: 400; height: 400
color: 'lightblue'
ListView{
width: 400; height: count * 30
model: 20
delegate: Rectangle{
id: rectDel
width: 200; height: 30
color: 'lightgreen'
border{
width: 1
color: 'black'
}
Text{
text: index
anchors.centerIn: parent
}
Rectangle{
width: 20; height: 20
radius: 10
color: 'red'
anchors{
verticalCenter: parent.verticalCenter
right: parent.right; rightMargin: 10
}
Text{ text: 'X'; anchors.centerIn: parent; }
MouseArea{
anchors.fill: parent
onClicked: {
rectDel.visible = false
rectDel.height = 0
}
}
}
}
}
}
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"
}
}
}
I have a file named page2.qml like below
Page {
id: page
Rectangle {
id: container
anchors.fill: parent
width: parent.width * 0.8
Rectangle {
id: title
anchors.top: parent.top
width: parent.width
height: 50
color: "salmon"
}
ListView {
id: listView
currentIndex: -1
anchors.top: title.bottom
anchors.bottom: parent.bottom
delegate: Rectangle {
height: 20
width: 100
border.color: "red"
color: "pink"
Text {
text: model.index
}
}
model: 100
}
}
}
the result is in this image:
Since the listview contain 100 item, how can i make the whole page scrollable? i can make just listview scrollable but not the whole page.
If you don't need the ListView to be scrollable by itself but your whole container need to, you could use a Repeater instead and put it inside a Column wrapped in a Flickable :
Flickable {
id: container
contentHeight: column.implicitHeight
contentWidth: width
width: parent.width * 0.8
height: parent.height
Column {
id: column
width: parent.width
Rectangle {
id: title
width: parent.width
height: 50
color: "salmon"
}
Repeater {
id: listView
model: 100
delegate: Rectangle {
height: 20
width: 100
border.color: "red"
color: "pink"
Text {
text: model.index
}
}
}
}
}
I have a few questions about GridLayout in QtQuickLayouts 1.3:
How should I make it , so the GridLayout places into CORRECT row/column every element of my grid even if the size of the element is not clearly specified by with or height parameter?
Let me remove the width and height and I will show you the broken layout. I will just comment it out:
Item {
id: test_item
//Layout.fillWidth: true
//height: 20
}
Full source code of the .qml file is here, and can be tested with bin/qmlscene:
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
ApplicationWindow {
width: 400
height: 500;
ColumnLayout {
anchors.fill: parent
GridLayout {
anchors.fill: parent
columns: 2
Label {
text:"Email:"
}
Rectangle {
width: 80; height: 20
border.color: "magenta"
}
Label {
text: "Full Name:"
Layout.fillWidth: true
}
Item {
id: test_item // the commented out portion, to show the flaw
//Layout.fillWidth: true
//height: 20
}
Label {
text: "Gender:"
}
RowLayout {
Layout.minimumHeight: 20
Layout.fillWidth: true
RadioButton {
text: "Male"
width: parent.width/2
height: 20
}
RadioButton {
text: "Female"
width: parent.width/2
height: 20
}
}
Label {
text: "Mobile phone:"
}
Rectangle {
width: 80; height: 20
border.color: "magenta"
}
}
Row {
Button {
text: "Cancel"
}
Button {
text: " Ok "
}
}
}
}
The 'broken` output looks like this:
While the correct output , with Item's size specified looks like this:
2) The second question. How do I load a component into a GridLayout cell via Loader using Component type? For example, this is my full source with the Component item and the component is missing when rendering:
import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
ApplicationWindow {
width: 400
height: 500;
ColumnLayout {
anchors.fill: parent
GridLayout {
anchors.fill: parent
columns: 2
Label {
text:"Email:"
}
Rectangle {
width: 80; height: 20
border.color: "magenta"
}
Label {
text: "Full Name:"
Layout.fillWidth: true
}
Loader {
id: test_item
sourceComponent: field_template
}
Label {
text: "Gender:"
}
RowLayout {
Layout.minimumHeight: 20
Layout.fillWidth: true
RadioButton {
text: "Male"
width: parent.width/2
height: 20
}
RadioButton {
text: "Female"
width: parent.width/2
height: 20
}
}
Label {
text: "Mobile phone:"
}
Rectangle {
width: 80; height: 20
border.color: "magenta"
}
}
Row {
Button {
text: "Cancel"
}
Button {
text: " Ok "
}
}
}
Component {
id: field_template
Item {
Layout.fillWidth: true
height: 33
Rectangle {
border.color: "blue"
color: "transparent"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.rightMargin: 10
TextEdit {
anchors.fill: parent
anchors.leftMargin: 5
anchors.topMargin: 3
anchors.rightMargin: 2
clip: true
text: "type here"
}
}
}
}
}
The picture of the output rendered by qmlscene is this:
I have correctly speecified witdht and height, why isn't the component being loaded with Loader ?
For the second question folibis is right in the comment. You just have to check the size. Here, is a working code.
...
Item {
Layout.fillWidth: true
//width: 80
height:20
Loader {
id: test_item
anchors.fill: parent
sourceComponent: field_template
}
}
...
Component {
id: field_template
Item {
Rectangle {
border.color: "blue"
color: "transparent"
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.rightMargin: 10
TextEdit {
anchors.fill: parent
anchors.leftMargin: 5
anchors.topMargin: 3
anchors.rightMargin: 2
clip: true
text: "type here"
}
}
}
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
}
}