I am starting with QT and trying to style a TextField using the following QML code:
property Component textfieldStyle: TextFieldStyle {
background: BorderImage {
source: control.focus ? "images/input-border-focused.png" : "images/input-border.png"
border.left: 0 ; border.right: 0 ; border.top: 0 ; border.bottom: 4
}
}
My question is: is there a way of setting a border like this and also an icon inside the field just like in the image below?
The blue part is the background of the window.
If so, how can it be done?
Thank you in advance.
Well since you have to use a Component for the TextFieldStyle, you are not restricted to use BorderImage, you can create your own Field using for eg a Rectangle like this
TextField {
style: TextFieldStyle {
textColor: "black"
background: Rectangle {
radius: 2
border.color: "red"
border.width: 3
Image {
width: 10
height: 10
source: "qrc:///inner.png"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 10
}
}
}
}
Since Rectangle has border property you can use it directly to set border.
Related
I'm currently trying to change the layout of a QML TreeView so that the expand icon (the arrow or triangle you have to click in order to show or hide the children elements).
I tried anchoring the icon to the right of the TreeView, but for some reason it's not working, it remains on the left despite everything. Do you have any hint?
Thanks a lot!
TreeView {
id: treeView
anchors.fill: parent
model: treeModResult
style: TreeViewStyle {
branchDelegate: Rectangle {
width: 15; height: 15
color: "#00000000"
anchors.right: treeView.right
Image {
id: expandArrow
source: styleData.isExpanded ? "qrc:/img/icn_arrow_top.svg" : "qrc:/img/icn_arrow_bottom.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
}
ColorOverlay {
anchors.fill: expandArrow
source: expandArrow
color: "#293147"
}
}
}
}
Update
This is what I currently have:
This is what I would like to have:
I had the same issue, I came up with the following solution, as anchoring wasn't working for me neither..
style: TreeViewStyle {
branchDelegate: Rectangle{
id: expandIcon
x: control.width - width
control.width represents the width of the treeview.
How do you set the color of the line in TextField to another color?
With Material theme you can change "Material.accent" color, but I want to change the permanent color, not only when the line gets focus.
There are at least 2 types of TextField - QtQuick2 and QtControls2. Assuming that you use the last one you can customize the control as you want, including the line color. For example:
TextField {
anchors.centerIn: parent
background: Item {
implicitWidth: 200
implicitHeight: 40
Rectangle {
color: "yellow"
height: 3
width: parent.width
anchors.bottom: parent.bottom
}
}
}
if you check source code of the Material style you see next:
background: Rectangle {
y: source.height - height - source.bottomPadding + 8
implicitWidth: 120
height: source.activeFocus || source.hovered ? 2 : 1
color: source.activeFocus ? source.Material.accentColor
: (source.hovered ? source.Material.primaryTextColor : source.Material.hintTextColor)
}
So for add support custom color of TextField line you need to add one property and replace source.Material.hintTextColor to your custom color.
TextField {
id: source
property color lineColor: "#ff00ff"
background: Rectangle {
y: source.height - height - source.bottomPadding + 8
implicitWidth: 120
height: source.activeFocus || source.hovered ? 2 : 1
color: source.activeFocus ? source.Material.accentColor
: (source.hovered ? source.Material.primaryTextColor : source.lineColor)
}
}
I'am using Qml to develop a system, I want to change TableViewColumn's default height and its border style. I just want to show the bottom/right borders, to look like table.
In your TableView you could define custom itemDelegate with borders and desired height https://doc.qt.io/qt-5/qml-qtquick-controls-tableview.html#itemDelegate-prop
TableView {
itemDelegate: Rectangle {
height: 30 // put your height here
border.color: "black"
border.width: 1
Text {
anchors.verticalCenter: parent.verticalCenter
color: styleData.textColor
elide: styleData.elideMode
text: styleData.value
}
}
}
You can use rowDelagate property of TableView component.
TableView {
id: idReadDataTableView
anchors.fill: parent
rowDelegate: Rectangle {
width: parent.width
height: 40
}
}
Below is my Qml code:
Button {
id: newMenu
anchors {
top: topMenu.top
topMargin: 15
left: topMenu.left
leftMargin: 16
}
text: "New"
iconSource: "../images/New.png"
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true //this line will enable mouseArea.containsMouse
onClicked: {
newProjectFileDlg.visible = true
}
onEntered: {
console.log(tt1);
}
}
style: ButtonStyle {
id: buttonStyle
background: Rectangle {
id: tt1
implicitWidth: 100
implicitHeight: 25
border.width: 0
radius: 4
color: mousearea.entered ? "lightsteelblue" : "#2e2e2e"
}
}
I want to access this button's style property, change the background.color when mouse is hover. But the console.log outpu is always
qrc:/qmls/menu.qml:40: ReferenceError: tt1 is not defined
How to get the element using JavaScript? Or do we have other approach to change background color when mouse is entered.
Answering to your question, you should define public property like:
Button {
id: root
property color backgroundColor: pressed ? 'skyblue'
: mousearea.entered ? "lightsteelblue"
: "#2e2e2e"
...
MouseArea { id: mousearea; ... }
style: ButtonStyle {
background: Rectanlge { color: root.backgroundColor; ... }
}
}
and then use is property to override default implementation.
But,
You are trying to use styles in a completely wrong way. Style is a visual representation of Control's state and should't be changed manually in run-time. So, a proper way is to bind control properties to style (e.g. using property control).
style: ButtonStyle {
background: Rectangle {
color: control.hovered ? 'lightsteelblue'
: 'skyblue'
}
}
You can achieve something similar without using styles by nesting a rectangle inside the button and then using the onHoveredChanged property to modify the opacity. An example is below. I did it this way to avoid conflicting with the normal button style's hover effect.
Button {
text: "Push me"
Rectangle{
id: myRectId
anchors.fill: parent
anchors.margins: 1
color: "green"
opacity : .2
}
onHoveredChanged: hovered ? myRectId.opacity = 0 : myRectId.opacity = .2;
}
This ends up looking like this:
How is it possible in QML to automatically stretch element so that all its childs fit in it? And how to specify spacing? For example, I would like to have a rectangle around a text. The rectangle should have some internal spacing.
If I write the following then the rectangle has a size of 0,0.
Rectangle {
color: "gray"
anchors.centerIn: parent;
Text {
text: "Hello"
}
}
If I try to fix it by using the Column element, as suggested in How to make QML items to grow to fit contents?, then I get a column through the whole window/parent,
Column {
anchors.centerIn: parent
Rectangle {
color: "gray"
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: "Hello"
}
}
Edit:
I have also tried to use the Flow element instead of Column, but then I got a row through the whole window/parent.
You can use the childrenRect property for this:
import QtQuick 2.0
Rectangle {
width: 320
height: 200
Rectangle {
color: "BurlyWood"
anchors.centerIn: parent
width: childrenRect.width + 20
height: childrenRect.height + 20
Text {
id: hello
x: 10
y: 10
text: "Hello"
}
Text {
anchors.left: hello.right
anchors.leftMargin: 10
anchors.top: hello.top
text: "World"
}
}
}
However, note that using childrenRect in combination with using anchors.centerIn: parent in one of the direct children yields a warning about a binding loop.
Setting the width and height manually works, but is a little ugly:
Rectangle {
color: "gray"
width: label.width+20
height: label.height+20
anchors.centerIn: parent
Text {
id: label
anchors.centerIn: parent
text: "Hello"
}
}
I don't think using chilrenRect property is sufficient (as suggested by Thorbjørn Lindeijer). It doesn't automatically take into account all various margins of the child(ren) element(s). If the latter changes, the root rectangle doesn't automatically adjust its size. I personally came with the following solution:
Rectangle {
color: "white"
implicitWidth: row.implicitWidth + extraLeft + extraRight
implicitHeight: row.implicitHeight + extraTop + extraBottom
property int extraMargin: row.anchors.margins ? row.anchors.margins : 0
property int extraTop: row.anchors.topMargin ? row.anchors.topMargin : extraMargin
property int extraBottom: row.anchors.bottomMargin ? row.anchors.bottomMargin : extraMargin
property int extraLeft: row.anchors.leftMargin ? row.anchors.leftMargin : extraMargin
property int extraRight: row.anchors.rightMargin ? row.anchors.rightMargin : extraMargin
RowLayout {
id: row
spacing: 50
anchors.fill:parent
anchors.margins: 50
anchors.leftMargin: 100
Label {
text: "hello"
}
Label {
text: "world"
}
}
}