Nested ListView in Qml - c++

I am trying to achieve this output [Refer snapshot :
click here]
I tried Using, since I am new to Qt not sure whether my approach of using repeater is right or wrong.
ListView {
id: outer
model: model1
delegate: model2
anchors.fill: parent
}
Component {
id: model1
Item {
Column{
Repeater {
model: 3
Rectangle {
id: rect
anchors.top: parent.bottom
width: 300
height: 30
color: listColor2[index]
}
}
}
}
}
Component {
id: model2
Column{
Repeater {
model: 4
Rectangle {
id: rect
width: 150
height: 30
color: listColor[index]
}
}
}
}

I have found the solution to my problem.
Obtained output click here
Rectangle {
width: 360
height: 360
ListView {
id: outer
model: 4
delegate:
Rectangle {
id: rect
color: listColor[index]
width: 60
implicitHeight: col.height
Column{
id: col
anchors.left: rect.right
Repeater {
id: lv2
model: 4
Rectangle {
id: rect2
color: listColor2[index]
width: 200
height: 20
}
}
}
}
anchors.fill: parent
}
}

Related

Provide activeFocus to Flickable

I have a QML component with a Flickable list and I need this Flickable to get activeFocus when I am clicking on it. I am trying to do it with MouseArea, but can't figure out how to make it work.
My tries:
FocusScope {
id: root
implicitHeight: 100
implicitWidth: 100
Flickable {
id: flickable
anchors.fill: parent
onActiveFocusChanged: console.log("Work!")
...
}
MouseArea {
anchors.fill: parent
onClicked: {
flickable.forceActiveFocus()
mouse.accepted = false
}
preventStealing: true
}
}
FocusScope {
id: root
implicitHeight: 100
implicitWidth: 100
MouseArea {
anchors.fill: parent
onClicked: flickable.forceActiveFocus()
Flickable {
id: flickable
anchors.fill: parent
onActiveFocusChanged: console.log("Work!")
...
}
}
}
In the first variant, my flickable is working, but MouseArea is not handling the click. In the second one, Flickable is not working, but MouseArea is handling the click.
So the question is how to correctly set activeFocus of Flickable on the click event?
Write id for your Flickable
and also Try this code :
import QtQuick 2.12
import QtQuick.Window 2.12
FocusScope {
id: root
width: 640
height: 480
Flickable {
id:flickable
width: parent.width
height: parent.height
contentHeight: mColumnId.implicitHeight
onActiveFocusChanged: console.log("Work!")
Column{
id : mColumnId
anchors.fill: parent
Rectangle {
color: "red"
width: parent.width
height: 200
Text {
anchors.centerIn: parent
text: "Element 1"
font.pointSize: 30
color : "white"
}
}
Rectangle {
color: "blue"
width: parent.width
height: 200
Text {
anchors.centerIn: parent
text: "Element 2"
font.pointSize: 30
color : "white"
}
}
Rectangle {
color: "yellow"
width: parent.width
height: 200
Text {
anchors.centerIn: parent
text: "Element 3"
font.pointSize: 30
color : "white"
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
flickable.forceActiveFocus()
mouse.accepted = false
preventStealing: true
}
}
}
}

How to display Popup of ComboBox above?

My custom ComboBox works is correctly, but I do not understand how to up popup with list of element above of combobox.
ComboBox {
id: pointsPositionComboBox
anchors.fill: parent
displayText: qsTr("Position point")
model: map.pointPositionModel
textRole: "name"
delegate: Row {
Rectangle {
id: delegateRect
width: pointsPositionRect.width - removePointRect.width
height: pointsPositionRect.height
color: {
if (!delegateRectMouseArea.containsMouse)
return "#25263C"
else if (delegateRectMouseArea.containsMouse
&& !delegateRectMouseArea.pressed) {
return "#5F8C6D"
} else if (delegateRectMouseArea.containsMouse
&& delegateRectMouseArea.pressed) {
return "#73AB84"
}
}
Text {
text: model.name
color: "white"
width: parent.width - removePointItem.width
font.pixelSize: pointsPositionComboBox.font.pixelSize
anchors.topMargin: pointsPositionRect.height / 3
anchors.left: parent.left
anchors.leftMargin: 5
}
MouseArea {
id: delegateRectMouseArea
anchors.fill: delegateRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
const latitude = model.position.latitude
const longitude = model.position.longitude
map.center.latitude = latitude
map.center.longitude = longitude
map.zoomLevel = model.zoomLevel
globalMapProperty.bearing = model.bearing
pointsPositionComboBox.popup.close()
}
}
}
Rectangle {
id: removePointRect
width: 30
height: 30
z: pointsPositionComboBox.z + 1
color: {
if (!removePointItemMouseArea.containsMouse)
return "#25263C"
else if (removePointItemMouseArea.containsMouse
&& !removePointItemMouseArea.pressed) {
return "#73A081"
} else if (removePointItemMouseArea.containsMouse
&& removePointItemMouseArea.pressed) {
return "#52785E"
}
}
Image {
id: removePointItem
anchors.centerIn: parent
source: removePointItemMouseArea.containsMouse ? "qrc:/icons/compass/remove_point_en.svg"
: "qrc:/icons/compass/remove_point_dis.svg"
}
MouseArea {
id: removePointItemMouseArea
anchors.fill: removePointRect
hoverEnabled: true
acceptedButtons: Qt.LeftButton
onClicked: {
if (hasUserMenuProperty.hasUserMenu()
&& !globalUserManager.hasAccessToPrivilege("controlMap"))
return
map.pointPositionModel.remove(map.pointPositionModel.index(index, 0))
}
}
}
}
}
Component.onCompleted: {
pointsPositionComboBox.popup.contentItem.implicitHeight = Qt.binding(function () {
// Делаем отображение только 10 элементов (остальные скроллом только)
return Math.min(pointsPositionRect.height * 10,
pointsPositionComboBox.popup.contentItem.contentHeight)
})
}
How to display a list of combo box elements from the top, and not from the bottom as in the photo?
P.s. I set implicitHeight for displaying element of combobox in Component.onCompleted
P.s.2 Now it looks like picture:
I've used the implicitHeight of the Popup to set its y property. Have a look at the source below. The default behavior of the Popup is when ever it fits below it will open up below, if there is not enough space below it will open above the ComboBox. The following code is a tweaked version of the Customizing ComboBox example from the Qt documentation.
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
width: 400
height: 300
Row {
anchors.centerIn: parent
ComboBox {
id: control
model: ["First", "Second", "Third"]
delegate: ItemDelegate {
width: control.width
contentItem: Text {
text: modelData
color: "#21be2b"
font: control.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
highlighted: control.highlightedIndex === index
}
indicator: Canvas {
id: canvas
x: control.width - width - control.rightPadding
y: control.topPadding + (control.availableHeight - height) / 2
width: 12
height: 8
contextType: "2d"
Connections {
target: control
function onPressedChanged() { canvas.requestPaint(); }
}
onPaint: {
context.reset();
context.moveTo(0, 0);
context.lineTo(width, 0);
context.lineTo(width / 2, height);
context.closePath();
context.fillStyle = control.pressed ? "#17a81a" : "#21be2b";
context.fill();
}
}
contentItem: Text {
leftPadding: 10
rightPadding: control.indicator.width + control.spacing
text: control.displayText
font: control.font
color: control.pressed ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 120
implicitHeight: 40
border.color: control.pressed ? "#17a81a" : "#21be2b"
border.width: control.visualFocus ? 2 : 1
radius: 2
}
popup: Popup {
y: myCheckBox.checked ? -implicitHeight + 1 : control.height - 1
width: control.width
implicitHeight: contentItem.implicitHeight
padding: 1
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
border.color: "#21be2b"
radius: 2
}
}
}
CheckBox {
id: myCheckBox
text: qsTr("above")
}
}
}

how can i create or achieve a chart like this in Qt?

I want to create a chart like this in qt. I already searched and can not find a way to do it.
I also can not find a way to customize Barchart and look like this in Widget Based Applications
Easy in QML!
import QtQuick 2.0
import QtQuick.Layouts 1.1
Rectangle
{
width: 600
height: 300
ListModel
{
id: dataModel
ListElement { label: "C.A"; value: 37 }
ListElement { label: "C.B"; value: 58 }
ListElement { label: "C.C"; value: 16 }
ListElement { label: "C.D"; value: 5 }
ListElement { label: "C.E"; value: 95 }
ListElement { label: "C.F"; value: 10 }
ListElement { label: "C.G"; value: 27 }
ListElement { label: "C.H"; value: 2 }
}
Rectangle
{
height: 4
width: layout.width
anchors.top: layout.bottom
anchors.horizontalCenter: layout.horizontalCenter
color: "#bbbdbe"
}
RowLayout
{
id: layout
width: 400
height: 200
spacing: 0
anchors.centerIn: parent
Repeater
{
id: rpt
property int barWidth: layout.width / count
model: dataModel
delegate:
Rectangle
{
width: rpt.barWidth
height: layout.height
color: "transparent"
Rectangle
{
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: 3
height: (parent.height * value) / 100
color: "#448bbe"
Rectangle
{
color: "#448bbe"
radius: width / 2
width: 8
height: 8
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
}
}
Text
{
y: parent.height + 3
anchors.horizontalCenter: parent.horizontalCenter
text: label
}
}
}
}
}
Screenshot
Since the OP didn't specify he wants a solution for a Qt widgets based application [he did after editing the question], the answer is:
Create your own QWidget class. Override the paintEvent and paint in it with a QPainter. I think there's plenty of examples if you google it.
Like this: http://doc.qt.io/qt-5/qtwidgets-painting-basicdrawing-example.html
Or this: http://programmingexamples.wikidot.com/qt-qpainter-example
Or this: Draw on QWidget
You can go for Custom QQuickPaintedItem here you can find an Example.

QML How to dynamically access ListView items

I have a ListView which has dynamically added Items, and what I kinda want to know is how I could access items for example by index. Specifically, I want to have the color of the item rectangle change when I change the color using the Color Dialog. I guessed it should be maybe possible to first set a variable to the current item before calling the color dialog and then in the onAccepted method change the color of that item using the variable, but I don't know how to achieve anything of this in QML, because I am rather new to QML. Maybe you can offer even a cleaner way to change the color of the item's rectangle when the color dialog was closed (onAccepted). Thx for any help! :)
import QtQuick 2.0
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.4
Rectangle {
id: listViewContainer
width: parent.width/10*9;
height: 50
Behavior on height {
NumberAnimation {
duration: 100;
}
}
gradient: Gradient {
GradientStop {position: 0.0; color: "white" }
GradientStop {position: 1.0; color: "silver" }
}
radius: 5
ColorDialog {
id: colorDialog
title: "Please choose a color"
onAccepted: {
console.log("You chose: " + colorDialog.color)
Qt.quit()
}
onRejected: {
console.log("Canceled")
Qt.quit()
}
}
Component {
id: playerDelegate
Item {
anchors.left: parent.left
anchors.right: parent.right
height: 50
Column {
Text { text: '<b>Name:</b> ' + name }
Row {
MouseArea {
width: 20
height: 20
onClicked: {
colorDialog.visible = true;
playerColor = colorDialog.color;
//open color dialog
}
Rectangle {
radius: 3
anchors.fill: parent
color: playerColor
}
}
}
}
}
}
ListView {
id: playerListView
anchors.fill: parent
model:
ListModel {
id: playerListViewModel;
ListElement {
name: "Bill Smith"
playerColor: "red"
}
}
delegate: playerDelegate
}
Button {
id: addPlayerButton
anchors.top: playerListView.bottom
anchors.left: playerListView.left
anchors.right: playerListView.right
style: ButtonStyle {
label: Text {
text: "Add new player"
horizontalAlignment: Text.Center
}
}
onClicked: {
root.addnewPlayer(playerListView); //dont worry about this method
playerListViewModel.append({name: "Billy", playerColor: "blue"});
listViewContainer.height += 50;
}
}
}
Here is a sure fire way to make a working colorDialog --
in playerDelegate
Component {
id: playerDelegate
Item {
anchors.left: parent.left
anchors.right: parent.right
height: 50
Column {
Text {
text: '<b>Name:</b> ' + name
}
/* Object to store value from color selector */
Item {
id: colorSelector
property color color: "#000000"
onColorChanged: { playerColor = color; }
}
/* box to display color */
Rectangle {
//Layout.fillWidth: true
height: 120
width: 120
anchors.left: button.right
//Layout.alignment: Qt.AlignHCenter
color: colorSelector.color
border.width: 1
border.color: "#000000"
}
/* button to open dialog -- can be mousearea or other clickable object */
Button {
id: button
text: "Browse..."
onClicked: {
colorDialog.color = colorSelector.color
colorDialog.open()
}
}
/* actual color dialog for this delegate */
ColorDialog {
id: colorDialog
modality: Qt.ApplicationModal
title: "Please choose a color"
onAccepted: colorSelector.color = currentColor
}
}
}
}

Qt qml - how to use component in its definition?

I have to implement TreeView in qml. Basically because each subtree is just TreeView itself, i want to use TreeView component in TreeView definition (this is that Repeater on the end).
This is part of code where i reference the component i am defining.
You can see that rootDelegate is actually id of the Component.
Problem is Qt gives error Unable to assign QQuickRow to QQmlComponent
Repeater {
model: childrens
delegate: rootDelegate
}
TreeView.qml
import QtQuick 2.0
Component {
id: rootDelegate
Column {
Row {
id: itemControl
spacing: 2
Rectangle {
anchors.verticalCenter: parent.verticalCenter
gradient: Gradient {
GradientStop { position: 0.0; color: "#EEEEEE" }
GradientStop { position: 1.0; color: "#404040" }
}
width: openChar.implicitWidth
height: openChar.implicitHeight - 6
radius: 3
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
}
Text {
id: openChar
text: "+"
color: "black"
anchors.centerIn: parent
}
}
Rectangle {
height: 1
color: "#A0A0A0"
width: 10
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: model.text
color: "white"
}
}
Repeater {
model: childrens
delegate: rootDelegate
}
}
}
You are trying to use a Сomponent recursively in itself, it is not allowed in Qml