QML: How to select radio button from listview? - qt

I have next listview component:
CustomListRadio.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import "."
Rectangle {
id: radio_content
x: 0
y: 40
width: 320
height: 158
color: "black"
property int counter: 0
property int savedIndex: 0
property int checkedIndex: 0
property variant internalModel
ButtonGroup {
id: buttonGroup
}
ListView {
id: list
x: 0
y: 0
width: 320
height: 158
model: parent.internalModel
anchors.fill: radio_content
delegate: RadioDelegate {
text: modelData
checked: index == radio_content.savedIndex
ButtonGroup.group: buttonGroup
font.pixelSize: 23
font.family: "Futura Condensed"
font.styleName: "Medium"
MouseArea {
anchors.fill: parent
onClicked: {
parent.checked = true
radio_content.checkedIndex = model.index
}
}
}
}
}
RadioDelegate.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
RadioDelegate {
id: control
text: qsTr("RadioDelegate")
checked: true
contentItem: Text {
leftPadding: control.indicator.width + control.spacing
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: "white"
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
indicator: Rectangle {
implicitWidth: 30
implicitHeight: 30
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 15
color: control.checked ? "#0088FF" : "white"
border.color: "#0088FF"
Rectangle {
width: 10
height: 10
x: parent.width / 2 - width / 2
y: parent.height / 2 - height / 2
radius: 5
color: "white"
visible: control.checked
}
}
background: Rectangle {
implicitWidth: 320
implicitHeight: 40
color: "black"
border {
color: "#383838"
width: 1
}
}
}
How add component
CustomListRadio {
id: radio_list
internalModel: msg.languageVariantList
savedIndex: msg.language
}
It creates a list of radiobuttons. It works well. But, I can't select default checked radio button. Selecting a switch with the mouse, works. But from the code, at best, my solution selects the switch only if the length of the list is equal to the number of visible elements.

Problem in RadioDelegate.qml, need to remove next string:
checked: true

Related

Set correct size for custom QML slider

I'm trying to create a reusable slider. I'm having trouble to set implicit sizes correctly so that the CustomSlider includes the Slider and the Label. I would like to have a implicit size specified, but let the user set a width for the slider itself.
I tried using childrenRect but that gives me a binding loop error.
How can I have the yellow background span across all the components: the slider and the green label?
Currently:
Would like:
CustomSlider.qml
Item {
id: root
property int startval: 0
property int endval: 20
property int sliderWidth: 200
// This results in binding loop
//implicitHeight: childrenRect.height
implicitHeight: control.height + label.height
implicitWidth: sliderWidth
Rectangle {
color: "yellow"
width: root.width
height: root.height
}
Slider {
id: control
stepSize: 1
anchors.centerIn: parent
snapMode: Slider.SnapOnRelease
width: root.sliderWidth
from: root.startval
to: root.endval
handle: Rectangle {
id: handleId
x: control.visualPosition * (control.width - width)
y: (control.height - height) / 2
width: 20
height: 20
radius: 20
color: "gray"
}
background: Rectangle {
y: (control.height - height) / 2
height: 4
radius: 2
color: "green"
Rectangle {
width: control.visualPosition * parent.width
height: parent.height
color: "red"
radius: 2
}
}
}
Label {
id: label
width: 20
height: 20
text: control.value
font.pixelSize: 15
color: "black"
x: handleId.x + control.x
y: handleId.y - 20
Rectangle {
color: "green"
anchors.fill: parent
opacity: 0.3
}
}
}
Main.qml
CustomSlider {
anchors.centerIn: parent
startval: 0
endval: 10
//sliderWidth: 100
}
I usually set the Width and height based on the parent.
I set sliderWidth: parent.width/2.0 and for your green label I add TextMetrics and calculate its width based on the text that it wants to show.
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
id: root
property int startval: 0
property int endval: 0
property int sliderWidth: parent.width/2.0
// This results in binding loop
//implicitHeight: childrenRect.height
implicitHeight: control.height + label.height
implicitWidth: sliderWidth
Rectangle {
color: "yellow"
width: root.width
height: root.height
}
Slider {
id: control
stepSize: 1
anchors.centerIn: parent
snapMode: Slider.SnapOnRelease
width: root.sliderWidth
from: root.startval
to: root.endval
handle: Rectangle {
id: handleId
x: control.visualPosition * (control.width - width)
y: (control.height - height) / 2
width: 20
height: 20
radius: 20
color: "gray"
}
background: Rectangle {
y: (control.height - height) / 2
height: 4
radius: 2
color: "green"
Rectangle {
width: control.visualPosition * parent.width
height: parent.height
color: "red"
radius: 2
}
}
}
Label {
id: label
width: t_metrics.tightBoundingRect.width +4
height: t_metrics.tightBoundingRect.height +7
text: control.value
font.pixelSize: 15
color: "black"
x: handleId.x + control.x
y: handleId.y - 20
Rectangle {
color: "green"
anchors.fill: parent
opacity: 0.3
}
}
TextMetrics {
id: t_metrics
text: control.value.toString()
}
}
Updated:
in CustomSlider.qml , changed it to this code:
import QtQuick 2.15
import QtQuick.Controls 2.15
Item {
id: root
property int startval: 0
property int endval: 0
property int sliderWidth: parent.width/2.0
implicitHeight: control.height + label.height
implicitWidth: sliderWidth
Rectangle {
color: "yellow"
width: root.width +10
height: root.height +control.height + label.height + t_metrics.tightBoundingRect.height +7
Slider {
id: control
stepSize: 1
anchors.centerIn: parent
snapMode: Slider.SnapOnRelease
width: root.sliderWidth
from: root.startval
to: root.endval
handle: Rectangle {
id: handleId
x: control.visualPosition * (control.width - width)
y: (control.height - height) / 2
width: 20
height: 20
radius: 20
color: "gray"
}
background: Rectangle {
y: (control.height - height) / 2
height: 4
radius: 2
color: "green"
Rectangle {
width: control.visualPosition * parent.width
height: parent.height
color: "red"
radius: 2
}
}
}
Label {
id: label
width: t_metrics.tightBoundingRect.width +4
height: t_metrics.tightBoundingRect.height +7
text: control.value
font.pixelSize: 15
color: "black"
x: handleId.x + control.x
y: handleId.y /2 + 4
Rectangle {
color: "green"
anchors.fill: parent
opacity: 0.3
}
}
TextMetrics {
id: t_metrics
text: control.value.toString()
}
}
}
This makes your text label shows inside the yellow rectangle and in main.qml I add one Row with labels and spinboxes for the test.
If you want that user to set sliderWidth or startval and endval and then show him Slider you need to create that object dynamically.
and if you want to be displayed in the Column and don't overlap you need ColumnLayout.
If you want to scroll them then you need to use ScrollView.
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Window {
width: 660
height: 480
visible: true
title: qsTr("Hello World")
ScrollView {
width: parent.width
height : parent.height
contentWidth: slidersColumn.width
contentHeight: slidersColumn.height
clip : true
ColumnLayout {
id: slidersColumn
anchors.fill: parent
spacing:50
}
}
function addSlider(sliderWidth,startval,endval) {
var obj = Qt.createComponent("CustomSlider.qml");
var slider = obj.createObject(slidersColumn);
slider.startval=startval;
slider.endval=endval;
slider.sliderWidth=sliderWidth;
}
Row
{
x: 0
y: 5
width: parent.width
height: 30
Label {
id: lbl_slider_width
text: qsTr(" Slider width ")
}
SpinBox {
id: spinBox_slider_width
editable: true
from:0
to:parent.width
}
Label {
id: lbl_startval
text: qsTr(" Startval ")
}
SpinBox {
id: spinBox_startval
editable: true
from:0
to:parent.width
}
Label {
id: lbl_endval
text: qsTr(" Endval ")
}
SpinBox {
id: spinBox_endval
editable: true
from:0
to:parent.width
}
Button {
id: button
text: qsTr(" Create Slider")
onClicked:
{
addSlider(spinBox_slider_width.value,spinBox_startval.value,spinBox_endval.value)
}
}
}
}
The result is:

adding a button on QT/QML drop down item

I want to style my QML based combo/dropdown box so that each item will have a "delete" button on it like so
How can I achieve this? is there any article or links I can refer to to achieve this?
I am using QML to design the widget.
You can simply customize a QC2 combobox starting from here:
https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-combobox
To this:
import QtQuick 2.12
import QtQuick.Controls 2.12
Rectangle {
id: root
width: 400
height: 400
ComboBox {
id: control
x: 50
y: 50
model: ["My Brackets 2021", "New Preset 22", "Super Br1", "New thingy", "Element of that list"]
delegate: ItemDelegate {
width: control.width - 20
contentItem: Text {
text: modelData
color: "#787878"
font: control.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
Button {
x: parent.width - 25
y: (parent.height - height) / 2
width: 30
height: 30
text: "\u26CC"
onClicked: { /* --Perform delete action here-- */ }
}
}
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" : "#B4C8DA";
context.fill();
}
}
contentItem: Text {
leftPadding: 10
rightPadding: control.indicator.width + control.spacing
text: control.displayText
font: control.font
color: control.pressed ? "#17a81a" : "#787878"
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 250
implicitHeight: 40
border.color: control.pressed ? "#17a81a" : "#B4C8DA"
border.width: control.visualFocus ? 2 : 1
radius: 20
}
popup: Popup {
y: control.height + 3
width: control.width
implicitHeight: contentItem.implicitHeight + 20
padding: 10
contentItem: ListView {
clip: true
implicitHeight: contentHeight
model: control.popup.visible ? control.delegateModel : null
currentIndex: control.highlightedIndex
ScrollIndicator.vertical: ScrollIndicator { }
}
background: Rectangle {
border.color: "#B4C8DA"
radius: 20
}
}
}
}
Will look like this:

QML - SpinBox - Data validation

I have the following SpinBox model which I am trying to recreate using the new QtQuick.Control 2, because this one it's using version 1. And I've encountered some problems which I am not sure how to solve.
On the validation side, I should not be able to write anything on the suffix side, just on the number part. Also I should not be allowed to remote the suffix from there while editing
My width should be fixed and I should not be allowed to write more than that.
My Code:
import QtQuick 2.6
import QtQuick.Controls 2
import QtQuick.Controls.Styles 1.4
import QtGraphicalEffects 1.0
SpinBox {
id: root
property color borderColor: "red"
property string multipleValuesTooltip: ""
property color backgroundColor: "yellow"
property bool showTooltip: true
font.pointSize: 10
property int maximumValue: 50
property int minimumValue: 0
property string suffix: ""
property int decimals: 0
to: maximumValue
from: minimumValue
editable: true
rightPadding: {
console.log(root.contentItem.height)
return Math.max(40, Math.round(root.contentItem.height))
}
textFromValue: function(value, locale) {
return qsTr("%1"+suffix).arg(value);
}
contentItem: TextInput {
z: 5
text: root.textFromValue(root.value, root.locale)
font: root.font
color: "white"
selectionColor: "#21be2b"
selectedTextColor: "#ffffff"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
validator: root.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
up.indicator: Rectangle {
height: parent.height / 2
anchors.right: parent.right
anchors.top: parent.top
implicitWidth: 20 // Adjust width here
implicitHeight: {
console.log(root.contentItem.height)
return root.contentItem.height - 10
}
color: root.up.pressed ? "red" : "pink"
Image {
source: "qrc:/resources/arrow-down.png"
height: Math.min(15, sourceSize.height)
width: Math.min(30, sourceSize.width)
anchors.centerIn: parent
rotation: 180
}
}
down.indicator: Rectangle {
height: parent.height / 2
anchors.right: parent.right
anchors.bottom: parent.bottom
implicitHeight: root.contentItem.height - 10
implicitWidth: {
console.log("W: ",root.width)
return 20
}
color: root.down.pressed ? "red" : "pink"
Image {
source: "qrc:/resources/arrow-down.png"
height: Math.min(15, sourceSize.height)
width: Math.min(30, sourceSize.width)
anchors.centerIn: parent
}
}
background: Item {
implicitHeight: root.height === 0 ? Math.max(30, Math.round(root.contentItem.height * 1.2)) : root.height
implicitWidth: root.contentItem.width + leftPadding +rightPadding
baselineOffset: root.anchors.baselineOffset
Rectangle {
id: baserect
anchors.fill: parent
color: "purple"
radius: 3
}
Rectangle { // Border only
anchors.fill: parent
border.color: "black"
color: "transparent"
radius: 3
}
Rectangle {
anchors.right: parent.right
anchors.rightMargin: root.rightPadding - 10
anchors.verticalCenter: parent.verticalCenter
color: "black"
height: parent.height - parent.height/5
width: 1
}
}
}
I couldn't find any documentation or any kind of information regarding this wherever I've searched for. If any of you could help me I would be really grateful.

QML CheckBox set text size

Is there a way to set size of text used in checkbox?
I have following code:
CheckBox {
text: qsTr("Use Delays")
checked: false
anchors.horizontalCenter: parent.horizontalCenter
onCheckedChanged:
{
middle.useDelays = checked
}
}
Thanks a lot!
You can define the Text item displayed by the CheckBox using CheckBoxStyle.label
import QtQuick.Controls.Styles 1.4
CheckBox {
style: CheckBoxStyle {
label: Text {
text: "Label"
font.pointSize: 16
}
}
}
For QtQuick Controls 2 you can do:
https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-checkbox
import QtQuick 2.12
import QtQuick.Controls 2.12
CheckBox {
id: control
text: qsTr("CheckBox")
checked: true
indicator: Rectangle {
implicitWidth: 26
implicitHeight: 26
x: control.leftPadding
y: parent.height / 2 - height / 2
radius: 3
border.color: control.down ? "#17a81a" : "#21be2b"
Rectangle {
width: 14
height: 14
x: 6
y: 6
radius: 2
color: control.down ? "#17a81a" : "#21be2b"
visible: control.checked
}
}
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
verticalAlignment: Text.AlignVCenter
leftPadding: control.indicator.width + control.spacing
}
}

QML pieMenu on draggable object

I've got a draggable object that is created by a Javascript, which is working fine. But when I create a PieMenu inside it, the object isn't created/visible in the Javascript context:
import QtQuick 2.8
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQml.Models 2.2
Rectangle {
id: rev
width: 100
height: 80
color: "transparent"
antialiasing: false
Drag.active: dragArea.drag.active
MouseArea {
id: dragArea
width: parent.width
height: parent.height + 10 // easier to get
anchors.centerIn: parent
drag.target: parent
drag.axis: Drag.XAndYAxis
onClicked: pieMenu.popup(mouseX, mouseY), console.log("clicked")
}
PieMenu {
id: pieMenu
MenuItem {
text: "Add vertical bar"
onTriggered: print("Action 2")
}
}
Gauge {
id: revgauge
anchors.fill: parent
anchors.margins: 10
orientation : Qt.Horizontal
minorTickmarkCount: 4
tickmarkStepSize : 5000
minimumValue: 0
maximumValue: 10000
Behavior on value {
NumberAnimation {
duration: 5
}
}
Text {
font.pixelSize: (parent.height / 3)
anchors.top : parent.top
font.bold: true
font.family: "Eurostile"
color: "white"
anchors.horizontalCenter: parent.horizontalCenter
}
style: GaugeStyle {
valueBar: Rectangle {
implicitWidth: rev.height /3
color: Qt.rgba(revgauge.value / revgauge.maximumValue, 0, 1 - revgauge.value / revgauge.maximumValue, 1)
}
}
}
}
Can Mousearea handle dragging and a PieMenu at once? If not how can it be solved?
Consider QML PieMenu boundingItem. It addresses an exact issue with MouseArea you presented.

Resources