Kivy - How resize button on "x" in BoxLayout? - button

I try to resize a button at the half of the width of the BoxLayout, but i don't know why that don't work on the 'x' axis.
Here my .kv file:
MainWidget:
<MainWidget>:
BoxLayout:
canvas.before:
Color:
rgba: (1,0,0,1)
Rectangle:
pos: self.pos
size: self.size
Button:
text: "+"
color: 0,0,0
size_hint: .5, .5 << HERE
pos_hint: {'center_x': .5,'center_y': .5}
canvas.before:
Color:
rgba: (1,0,1,1)
Rectangle:
size: self.size
pos: self.pos
and what i got:
How can I resolve tis issue?

To have your button half the width/height of the BoxLayout you can set the size_hint to None, None, then set the width and height with the parent settings divided by 2. See example below:
Button:
text: "+"
color: 0,0,0
size_hint: None, None
width: self.parent.width/2
height: self.parent.height/2
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas.before:
Color:
rgba: (1,0,1,1)
Rectangle:
size: self.size
pos: self.pos
I also changed the BoxLayout to a FloatLayout so that the pos_hint can work properly.
Hope this helps!

Related

How can I animate a button's color so it changes from right to left?

I have this simple Rectangle and i want to animate it's color change in a way that the new color fills in from right to the left of it.
Rectangle{
width:100
height:150
color:"green"
}
What should I do? What kind of Animation or Transition do I need in this case?
First draw a simple Rectangle with the original color, "green" in this example:
Rectangle{
width:100
height:150
color:"green"
}
Then draw another rectangle on top but with width equal to 0 and the new color, "red" in this example:
Rectangle{
id: newColorRect
width:0
height:150
color:"red"
}
Finally with a animation you can animate the color change, changing the width of the newColorRect rectangle.
PropertyAnimation {
id: colorAnimation
target: newColorRect
properties: "width"
to: 100
duration: 1000
}
Component.onCompleted: {
colorAnimation.start()
}

How to set TextField's underline color?

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)
}
}

How can i set text align from bottom to top in qml?

I have a background image a and i want to right the text align from bottom to top.Just like the image showed as following. In my case, the background image is fixed, i cannot rotate it,so i just tried to rotate text!However, i cannot align it well!
Background Image(cannot be rotated)
The result i want(just like left align,center align and rotate -90)
I tried this code,but not work! I think the reason is the rotation center!
Text {
text: name;
anchors.verticalCenter: parent.verticalCenter; // Centering text
anchors.left: parent.left;
anchors.leftMargin: 18;
rotation: -90
}
If i rotate the background image 90 degree. Then apply my code and rotate the content(background and text) will get good result! However i cannot rotate the background image! How can i set text align from bottom to top in qml?
Anchoring with rotation might be at odds to manage. You can make it simple:
Rectangle{
color: "grey"
width: 50
height: 300
Text{
//1. Place Text box symmetrically below background, edge to edge
width: parent.height
height: parent.width
y:parent.height
text: "TableA Description 15"
verticalAlignment: Text.AlignVCenter
// comment below 2 lines to see how it looks before rotation
//2 pivot top left of text box and rotate text -90
transformOrigin: Item.TopLeft
rotation: -90
}
}
Transform provides more complex transformations for the QML item. In your case, check demo in below, it shows Text rotate itself -90 degree. and you can adjust the rotate point by setting the origin.x origin.y properties.
Rectangle{
width: 100; height: 300
color: "lightblue"
Text{
id: test
text: "TestMe"
transform: [
Rotation {
origin.x: test.paintedWidth/2; origin.y: test.paintedWidth/2; angle: -90
},
Translate{
y: (test.parent.height - test.paintedWidth)/2
}
]
}
}

Transparent button text over the background

I am trying to make transparent text in qml.
I have a customized button:
ApplicationWindow {
visible: true
width: 320
height:240
style: ApplicationWindowStyle {
background: Image { // paste any url here
source: "https://t4.ftcdn.net/jpg/01/05/18/57/240_F_105185755_w384KDBvemK5Mn4oXzrWbCz9SRvHuDIh.jpg"
}
}
Button
{
anchors.centerIn: parent
style: ButtonStyle
{
padding
{
left: 16
right: 16
top: 8
bottom: 8
}
background:
Rectangle
{
antialiasing: true
color: control.pressed ? "#d1d1d1" : control.hovered ? "#666" : "transparent"
border.color: "white"
radius: height/2
border.width: 1
}
label:
Text
{
text: "buttonText"
color: control.pressed ? "white" : control.hovered ? "#00000000" : "white"
}
}
}
}
All I want is to have transparent text in button in hovered state. Text should have the color of background. Example:
upd. I need this to work without shaders on slow pc.
One option would be to use a custom QQuickPaintedItem and use a QPainterPath to draw the "text shaped hole".
Basically like this
void MyItem::paint(QPainter *painter)
{
QPainterPath path;
path.addRect(0, 0, width(), height());
path.addText(textX, textY, font, yourText);
painter->setBrush(yourBackgroundColor);
painter->setPen(Qt::transparent);
painter->drawPath(path);
}
The position, i.e. textX and textY, would have to be calculated manually I am afraid, though QFontMetrics::boundingRect() should help there.

Is there any way to specify different radii for different corners

Can anyone help me how to round only one corner of a rectangle like shown in attached pic where red rectangle is my child rectangle.
Actually, I have a rectangle where all four corners rounded(radius 10). Now, i want to draw a new rectangle inside this and expecting only that particular corner should be rounded who touches the parent's round corner.
Rectangle
{
id: parent
radius: 10
width: 168
height: 168
visible: true
color: "black"
Rectangle
{
id: child
width: 100
height: 40
color: "red"
}
}
I tried to do this with adding clip property in child but nothing happened.
Here is a simple example.
It is rounded in the upper left corner, but is easily adjusted to any other corner. Only one corner is supported in this solution, but it might be enough for you?
More corners are little more complex, so ask again if you would need those aswell.
Rectangle {
anchors.centerIn: parent
id: root
radius: 20
width: 300
height: 300
Rectangle {
id: clipper
width: 100
height: 100
color: 'transparent'
clip: true
Rectangle {
id: clipped
width: parent.width + radius
height: parent.height + radius
radius: root.radius
color: 'red'
}
}
}
Not with the stock Rectangle:
The same radius is used by all 4 corners; there is currently no way to
specify different radii for different corners.
In C++ you could specify a horizontal and vertical radius, but still not per-corner radius. If you want such functionality, you will have to implement your own QQuickItem with the geometry node and all.
The result you want to achieve in the image could also be achieved with clipping, however unfortunately, in QML clipping only works for the item's rectangle, not the actual item geometry.
It will be easiest to achieve the desired effect using a BorderImage element. It enables to specify a different sub-image for every corner:
It is possible using Shape item as below:
Shape {
id: advancedShape
width: 100; height: 40
vendorExtensionsEnabled: true
layer.enabled: true
layer.samples: 4
layer.smooth: true
// set following properties to specify radius
property real tlRadius: 0.0
property real trRadius: 15.0
property real brRadius: 0.0
property real blRadius: 0.0
ShapePath {
strokeColor: "transparent"
fillColor: "red"
startX: 0; startY: advancedShape.tlRadius
PathArc {
x: advancedShape.tlRadius; y: 0
radiusX: advancedShape.tlRadius; radiusY: advancedShape.tlRadius
useLargeArc: false
}
PathLine {
x: advancedShape.width - advancedShape.trRadius; y: 0
}
PathArc {
x: advancedShape.width; y: advancedShape.trRadius
radiusX: advancedShape.trRadius; radiusY: advancedShape.trRadius
useLargeArc: false
}
PathLine {
x: advancedShape.width; y: advancedShape.height - advancedShape.brRadius
}
PathArc {
x: advancedShape.width - advancedShape.brRadius; y: advancedShape.height
radiusX: advancedShape.brRadius; radiusY: advancedShape.brRadius
useLargeArc: false
}
PathLine {
x: advancedShape.blRadius; y: advancedShape.height
}
PathArc {
x: 0; y: advancedShape.height - advancedShape.blRadius
radiusX: advancedShape.blRadius; radiusY: advancedShape.blRadius
useLargeArc: false
}
PathLine {
x: 0; y: advancedShape.tlRadius
}
}
}
and result will be as this:
NOTE The builtin Rectangle has more performance than Shape, but I recommend Shape over masking because it works on any environment.
NOTE 2 I think the most true way in production is using BorderImage as #dtech suggested IF the radius is known and you don't need to change radius dynamically.
Created this from a bunch of rectangles. Two big rectangles and 4 smaller optionally rounded squares. This way you can also make different radii for each corner, not only turning them on and off. You just need to make sure that you don't want a too big rounding, because then the rounded rect would stick out.
Rectangle {
id: clipper
width: 10
height: 10
color: "transparent"
clip: true
Rectangle {
id: clipped
width: 30
height: 30
radius: 8
color: "red"
}
}

Resources