Customized radio button in qml - qml

I want a window with 3 push button but this push buttons should work like radio button!
so this is my code:
Rectangle {
id: sideButton
color: sideButtonMouseArea.containsMouse ? '#DDDDDD' : '#F4F4F4'
property string text: 'Button'
MouseArea {
id: sideButtonMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
parent.color = '#4872E8'
sideButtonLabel.color = '#E2EBFC'
}
}
Text {
id: sideButtonLabel
text: sideButton.text
font.pixelSize: 20
font.family: 'Tahoma'
anchors.centerIn: sideButton
color: '#787878'
}
}
I use this rectangle instead button but it has a proble when click on other button for 2end time
how could i fix it?

This code works for me:
MyRadioGroup.qml
import QtQuick 1.0
QtObject {
property Item selected : null
}
MyRadioButton.qml
import QtQuick 1.0
Rectangle {
id: sideButton
property string text: 'Button'
property MyRadioGroup radioGroup
color: radioGroup.selected === sideButton ? '#E2EBFC' :
(sideButtonMouseArea.containsMouse ? '#DDDDDD' : '#F4F4F4')
MouseArea {
id: sideButtonMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: sideButton.radioGroup.selected = sideButton
}
Text {
id: sideButtonLabel
text: sideButton.text
font.pixelSize: 20
font.family: 'Tahoma'
anchors.centerIn: sideButton
color: radioGroup.selected === sideButton ? '#E2EBFC' : '#787878'
}
}
main.qml
import QtQuick 1.0
Rectangle {
height: 600
width: 600
MyRadioGroup {
id: radioGroup1
}
Column {
anchors.fill: parent
MyRadioButton {
anchors { left: parent.left; right: parent.right }
text: "Button 1"
radioGroup: radioGroup1
height: 100
}
MyRadioButton {
anchors { left: parent.left; right: parent.right }
text: "Button 2"
radioGroup: radioGroup1
height: 100
}
MyRadioButton {
anchors { left: parent.left; right: parent.right }
text: "Button 3"
radioGroup: radioGroup1
height: 100
}
MyRadioButton {
anchors { left: parent.left; right: parent.right }
text: "Button 4"
radioGroup: radioGroup1
height: 100
}
}
}
What it does: I've created container MyRadioGroup to hold currently selected item. Then, I declaratively bind its selected property with color property of my MyRadioButton-s, so it will update on every selected change.
Having that said, please check, that you component provider doesn't already contain some stuff like this --- maybe you are reinventing the wheel.

Related

Automatic row wrapping on elements in QML layout

Is there a QML layout or some configuration that will automatically wrap QML items to the next row if the width of the next element exceeds the width of the specified layout?
When I use a QML GridLayout, the items just go off the edge of the window and are clipped:
GridLayout {
id: header_focused_container;
width: parent.width;
anchors.margins: 20;
Text {
text: "header_focused_container.width=" +
header_focused_container.width +
" and my width is =" + width
}
Rectangle { height:20; width:250; color: "red" }
Rectangle { height:20; width:250; color: "blue" }
Rectangle { height:20; width:250; color: "green" }
}
When I look at Qt's documentation page labeled "Scalability" I see very manual scaling going on. Basically, they're suggesting that I need compute the needed columns.
Is there some sort of layout type or configuration that will do auto-wrapping of the items?
You can use Flow:
import QtQuick 2.5
import QtQuick.Window 2.0
Window {
visible: true
width: 400
height: 200
Flow {
id: header_focused_container
anchors.fill: parent
Text {
text: "blah"
}
Rectangle { height:20; width:250; color: "red" }
Rectangle { height:20; width:250; color: "blue" }
Rectangle { height:20; width:250; color: "green" }
}
}

Unable to position custom styled Tumbler

I am trying to give a Tumbler my own style. I declare the Tumbler like this:
Tumbler {
style: MyTumblerStyle {}
height: UIConstants.smallFontSize * 10
width: UIConstants.smallFontSize * 3
TumblerColumn {
model: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
}
}
where MyTymblerStyle is defined like this:
TumblerStyle {
id: root
visibleItemCount: 5
background: Rectangle {}
foreground: Item {}
frame: Item {}
highlight: Item {}
delegate: Item {
id: delRoot
implicitHeight: (control.height) / root.visibleItemCount
Item {
anchors.fill: parent
Text {
text: styleData.value
font.pixelSize: UIConstants.smallFontSize
font.family: UIConstants.robotoregular
anchors.centerIn: parent
scale: 1.0 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6
color: styleData.current?UIConstants.color:"black"
opacity: 1 - Math.abs(styleData.displacement/(root.visibleItemCount-3))
}
}
}
}
I use it in a Row like this:
Row {
MyTumbler {}
StandardText {
color: UIConstants.color
text: "Uhr"
}
}
Now, the result looks like this:
As you can see, the "Uhr" text center is aligned to the top of the Tumbler. Also the Row does not seem to recognize the real width of the Tumbler.
Why? It does work when I do not use MyTumblerStyle.
The problem isn't your style, it's the width assignment.
It helps to break out the Rectangles at a time like this:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Extras 1.3
ApplicationWindow {
title: qsTr("Hello World")
width: 300
height: 600
visible: true
Column {
anchors.centerIn: parent
Tumbler {
id: tumbler
width: 30
TumblerColumn {
model: 25
}
Component.onCompleted: print(width, height, implicitWidth, implicitHeight)
}
Rectangle {
width: tumbler.implicitWidth
height: tumbler.implicitHeight
color: "transparent"
border.color: "blue"
Text {
text: "Tumbler implicit size"
anchors.fill: parent
wrapMode: Text.Wrap
}
}
Rectangle {
width: tumbler.width
height: tumbler.height
color: "transparent"
border.color: "blue"
Text {
text: "The size you gave"
anchors.fill: parent
wrapMode: Text.Wrap
}
}
}
}
(I don't have access to UIConstants, so I guess the width you set)
The implicitWidth of Tumbler is calculated based on the width of each individual TumblerColumn. This allows you to set individual widths for columns, something that is necessary for scenarios where some are wider than others, for example:
So, you should also set the width of your column, or, preferably, only set the width of your column, and not the entire Tumbler:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Extras 1.3
ApplicationWindow {
width: 300
height: 600
visible: true
Row {
anchors.centerIn: parent
Tumbler {
id: tumbler
TumblerColumn {
model: 25
width: 30
}
}
Text {
text: "Uhr"
}
}
}
This also explains why the Text is weirdly positioned; the Row sees 30 pixels, but the column still has its original (much wider) width.

QML Row element refuses to work

I know I should be using Row, Column etc. rather than items anchored by ID to make my code simpler and easier to read. But they refuse to work most of the time. For example, in this case:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ListView {
id: listView
anchors.fill: parent
topMargin: spacing
anchors.leftMargin: spacing
anchors.rightMargin: spacing
clip: true
spacing: 0.5 * pxPermm
model: SqlQueryModel {}
delegate: Rectangle {
id: delegateItem
color: "white"
height: 14 * pxPermm
width: listView.width
clip: true
Row {
id: row
anchors.fill: delegateItem
spacing: pxPermm
Image {
height: row.height
width: height
source: "qrc:/resources/ryba.jpg"
fillMode: Image.PreserveAspectCrop
}
Item {
id: textItem
height: row.height
Label {
anchors.left: textItem.left
anchors.top: textItem.top
text: nazov
font.bold: true
}
Label {
anchors.left: textItem.left
anchors.bottom: textItem.bottom
text: cas
}
}
}
}
}
This shows two Labels on the top of an Image in the delegate of list view. Not two labels to the right of the image, as you would expect. However, this code works:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ListView {
id: listView
anchors.fill: parent
topMargin: spacing
anchors.leftMargin: spacing
anchors.rightMargin: spacing
clip: true
spacing: 0.5 * pxPermm
model: SqlQueryModel {}
delegate: Rectangle {
id: delegateItem
color: "white"
height: 14 * pxPermm
width: listView.width
clip: true
Row {
id: row
anchors.fill: delegateItem
spacing: pxPermm
Image {
height: row.height
width: height
source: "qrc:/resources/ryba.jpg"
fillMode: Image.PreserveAspectCrop
}
Label {
text: nazov
font.bold: true
}
}
}
}
Of course I need to show more than one label in the delegate. What am I missing here?
It turns out that Item has zero width by default. The code works properly after the width is set:
Item {
id: textItem
height: row.height
width: childrenRect.width
// labels etc
}

Detect Clicks outside QML Window

How do i detect clicks outside Window {} in QML ?
Rectangle {
id: topLevel
height: 400; width: 400
Window {
id: windowObj
color: "blue"
height: 200; width: 200
onActiveChanged { console.trace(); visible = false; }
}
Component.onCompleted: windowObj.visible = true
}
Suppose I click on some part of topLevel outside windowObj.
onActiveChanged works on Windows but not on MAC.
{Using: QtQuick 2.1, QtQuick.Window 2.1, QML/Qt 5.2.0}
Put a MouseArea in your topLevel Rectangle and let the event pass through
Rectangle {
id: topLevel
MouseArea{
anchors.fill : topLevel
propagateComposedEvents : true
onClicked : console.log("clickoutside");
}
Window {
id: windowObj
color: "blue"
height: 200; width: 200
onActiveChanged { console.trace(); visible = false; }
}
}

Using InputMask in QML

I have a small display window, that should hold an InputMask like "0000.00". When clicking on the Number-Buttons from 0 to 9, the display should show the respective numbers, for example: 0345.89
Here is my code:
TextInput {
id: displayNumbers6Text
cursorVisible: true
focus: true
validator: RegExpValidator {
regExp: /[0-9]+/
}
inputMask: "0000.00"
maximumLength: 7
}
And for the Buttons:
Button {
width: parent.width*0.3
height: parent.height*0.15
buttonColor: "#000000"
MouseArea {
anchors.fill: parent
onClicked: {
displayNumbers6Text.text = "1"
}
}
}
But it doesn't function. What am I doing wrong?
When you assign text property, you reset this value to "1".
If what you are trying is to insert a value when clicking on a button, you can try this :
import QtQuick 2.0
Rectangle {
width: 360
height: 200
TextInput {
id: displayNumbers6Text
width: parent.width
height: parent.height * 0.5
cursorVisible: true
focus: true
validator: DoubleValidator {
}
inputMask: "0000.00"
maximumLength: 7
function appendNum(num) {
var dotPos = text.indexOf(".");
if (dotPos == 4)
text += num;
else
text = text.substr(0, dotPos) + num + text.substr(dotPos);
}
}
Rectangle {
width: parent.width*0.3
height: parent.height*0.15
anchors.top: displayNumbers6Text.bottom
color: "black"
MouseArea {
anchors.fill: parent
onClicked: {
console.log(displayNumbers6Text.text);
displayNumbers6Text.appendNum("1");
}
}
}
}
You can use DoubleValidator instead of a general RegexValidator, it will be more readable.
I add an appendNum function to TextInput to insert a value at the end of the text string. Note that the dot character is always in the string, beacause of the inputMask you set