RGB and conditional instruction in .kv file - kivy

So I've been working on an application, and tried to use a conditional kv instruction in kv, as described here.
<myWidget#Widget>:
size: self.parent.width-self.height*0.5, self.parent.height/12
selected: False
canvas:
Color:
rgb: 1,1,0 if self.selected else 1,1,1
Rectangle:
pos: self.pos
size: self.parent.width-self.height*0.5, self.parent.height/12
My problem is that I don't understand the rgb behaviour : while the colours in this example work fine (turns to yellow when selected and back to white when unselected), other colour combinations will give unpredictable colors, or no result at all.
Could someone explain to me what actually happens to the rgb property ?

This is being parsed as (1, 1, (0 if self.selected else 1), 1, 1), which obviously isn't what you want but (as you note) happens to work in the case of yellow/white. Try instead
rgb: (1,1,0) if self.selected else (1,1,1)

Related

Kivy not responding to RGBA values

While giving the background color attribute in the .kv file for a button, and the value in two of the rgba fields goes above 220.0/255, it turns back to the default grey color.
My code excerpt with the FloatLayout
Button:
size_hint : 0.95/18, 0.1
pos_hint : {"center_x" : 0.95, "center_y" : 0.925}
font : 40
background_color: 1.0, 225.0/255, 228.0/255, 0
color: 211.0/255, 54.0/255, 112.0/255, 1
text: "Sample Text"
halign : "center"
I tried decreasing the values of the rgb fields and its working, but it isn't giving the color above the 220.0/255 value. I tried converting it to up to two decimal float, and it is still returning the same.

How to use Color with RGB or hex value in SwiftUI using Swift 5? [duplicate]

This question already has answers here:
How can I create a UIColor from a hex string?
(49 answers)
Closed 2 years ago.
The community reviewed whether to reopen this question 12 months ago and left it closed:
Original close reason(s) were not resolved
I am currently trying to change the background color of a Label in SwiftUI. As far as I know, SwiftUI takes a View as the parameter for the background Modifier.
However, I encountered a problem I am not able to fix:
I would like to change the background color of my Label by using a hex code or an RGB value. Because of some reason, when doing so the background color always changes to white.
This works perfectly fine:
Label(
title: { Text("someTitle") },
icon: { Image(systemName: "someName") }
)
.background(Color.purple) // Using the provided standard Colors works perfectly fine.
However, I would like to create a background color using a hex or RGB value:
.background(Color(Color.RGBColorSpace.sRGB, red: 92, green: 225, blue: 230, opacity: 1))
// or
.background(Color(UIColor(red: 220, green: 24, blue: 311, alpha: 1)))
This does not work and the background color of the Label always changes back to white. How to achieve this goal?
The UIColor init method UIColor(red:green:blue:alpha) takes float values from 0 to 1 for each value.
Any value ≥ 1.0 is going to "max out" that color. So an expression like UIColor(red: 220, green: 24, blue: 311, alpha: 1) will set all 3 color channels and alpha to 1.0, resulting in white. So would UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
You could create an extension to UIColor that adds convenience initializers that would take values of different types. First, and initializer that would take values from 0-255 for each. Then you could create another intializer UIColor.init(hexString:String).
The one that took values from 0-255 would be a lot easier to write. The one that took hex strings would involve implementing a hex parser. I bet somebody has already written it though.
Take a look at this code, for example:
https://gist.github.com/anonymous/fd07ecf47591c9f9ed1a

Positioning images with FloatLayout

This is driving me insane. I'm trying to position an image to the top of the main window with FloatLayout. Below is a simplified example.
It seems that a button is fine, but an image defaults to a 100x100 square (yes, I think I've read that somewhere) and the top bounding box of the image is at the top of the screen, not the image.
How can I force the image (top of the rectangle) to the top of the window like the button is?
Screen_showing example_button_and_image
import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.config import Config
Config.set('graphics', 'width', '480')
Config.set('graphics', 'height', '800')
class MyApp(App):
def setOrientation(self, orient):
""""""
self.orient = orient
def build(self):
return FloatLayout()
if __name__ == "__main__":
app = MyApp()
app.setOrientation(orient="vertical")
app.run()
<FloatLayout>:
Image:
source: 'image_400x90.png'
pos_hint: {'left':1, 'top':1}
size_hint: None, None
allow_stretch: False
keep_ratio: True
Button:
font_size: 30
color: 0,1,0,1
size_hint: 0.3, 0.1
text: "TopRight"
pos_hint: {'right':1, 'top':1}
That happend because the Image is a Widget and "the real image" (the picture) is a texture of that Widget, and by default, the image is centered and fits inside the widget bounding box. If you don’t want that, you can set allow_stretch to True and keep_ratio to False. (docs)
For understand that you can add a canvas with a rectangle in the Image Widget like this:
Image:
canvas:
Color:
rgba: 1, 1, 1, 0.5
Rectangle:
pos: self.pos
size: self.size
source: 'dog.jpg'
pos_hint: {'left':1, 'top':1}
size_hint: None, None
allow_stretch: True
keep_ratio: False
And then you can see why the image doesn't do what you want
another pic (the image(texture) is centered and fits inside the widget):
One thing you can do is set allow_stretch: True and keep_ratio: False
This is the result: (set the size with size_hint)
Favcau gives one solution above (and thanks), but I have found what I think is more obvious. All it needs is to have the size defined in the kv file.
Image:
id: image2
source: 'image_400x90.jpg'
pos_hint: {'left':1, 'top':1}
size_hint: None, None
size: 400, 90
allow_stretch: True
keep_ratio: False

Print button background color

Hi is there any way to print out selected button background color as string value?? For now when i click button and try to print value it gives be something like this -:
Optional(UIExtendedSRGBColorSpace 0.870588 0.721569 0.529412 1)
can I get color name somehow?Like Green,Blue?
This what you get here is color space in RGBA format, given:
Red: 0.870588
Green: 0.721569
Blue: 0.529412
Alpha: 1
If you do some math and multiply these numbers by 255, you get:
R: 221,99994
G: 184,000095
B: 135,00006
which looks like this:
https://www.colorcodehex.com/ddb887/
I guess there is no way to the absolute name of color, except you make enum with ranges and setup colors from the ranges... but I think No one is so crazy to do this... so you have to stick with this for now :)

kivy: How to change Switch default from ON/OFF to OPEN/CLOSE or to YES/NO?

To be more clearly, I want the text of the Switch changed from On/Off to Open/Close or Yes/No. I did not find out how to do it. Thanks.
You can hack this by changing the background image of the right rectangle in the Switch.
You can make an icon that is 83x32 pixels like the widget.
I Made a very ugly example on sumo an online photoeditor:
Then I saved it as images/icon.jpg
If you want to change the slider too, its 43x32 pixels.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.switch import Switch
class MyGui(Widget):
def __init__(self,**kwargs):
super(MyGui,self).__init__(**kwargs)
self.switch = Switch()
self.switch.canvas.children[2].source = "images/icon.jpg" # The slider is the last element, so in that case -> children[-1].source
self.add_widget(self.switch)
class MyApp(App):
def build(self):
return MyGui()
if __name__ == '__main__':
MyApp().run()
If you want to do this in kv language, you could do like this:
from kivy.lang import Builder
Builder.load_string("""
<MyGui>:
Switch:
canvas:
Color:
rgb: 1,1,1
Rectangle:
source: 'switch.jpg' # make or download your background jpg
size: sp(83), sp(32)
pos: int(self.center_x - sp(41)), int(self.center_y - sp(16))
Rectangle:
source: 'switch_slider.jpg' # make or download your slider jpg
size: sp(43), sp(32)
pos: int(self.center_x - sp(41) + self.active_norm_pos * sp(41)), int(self.center_y - sp(16))
""")
class MyGui(Widget):
pass
The switch text is sadly not a text but an image. You can find the kv file here. You should be able to provide a different theme (see here) or you can override the class and implement your own rendering (which then displays OPEN/CLOSE) instead of the ON/OFF.
If you don't intend to change its whole appearance, you can patch the style.kv and use a little bit of canvas instructions to create a widget of your taste. ^.^
(and it's a lot more flexible than creating image for each different switch, if you don't want to change its color)
from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<Custom#Switch>:
values: ['OFF', 'ON']
canvas:
Color:
rgb: 0.2, 0.709, 0.898, 1
Rectangle:
size: [sp(41.5), sp(20)]
pos: [self.center_x - sp(41.5), self.center_y - sp(10)]
Color:
rgb: 0.4, 0.4, 0.4, 1
Rectangle:
size: [sp(41.5), sp(20)]
pos: [self.center_x, self.center_y - sp(10)]
Label:
text: '[b]{}[/b]'.format(root.values[0])
markup: True
font_size: 13
pos: [root.center_x - sp(70), root.center_y - sp(50)]
Label:
color: 0.75, 0.75, 0.75, 1
text: '[b]{}[/b]'.format(root.values[1])
markup: True
font_size: 13
pos: [root.center_x - sp(30), root.center_y - sp(50)]
<Test>:
Custom:
Switch:
Custom:
values: ['Yes', 'No']
''')
class Test(BoxLayout): pass
runTouchApp(Test())
If you're using #el3in's solution make sure to clarify canvas.after instead of canvas otherwise the original switch image stays on top ;)

Resources