How To Target Canvas.before In Kv
Solution 1:
You cannot change the variables created in kv
. Once your app is running, those variables no longer exist. You can, however, use a Property that is created in kv
(or python) as an attribute of a class (or the App
itself). Such Properties
continue to exist while the App
is running, and kivy recognizes such Properties
and will automatically handle changes to those Properties
. An example is to create a new class that extends Button
and has Properties
like you want:
<-MyButton@Button>:
# create the desired properties
btn_color_not_pressed: [.5, .5, .5,1]
btn_color_pressed: [.25, .25, .25, 1]
canvas:
Color:
# reference the above properties
rgba: self.btn_color_not_pressed if self.state=='normal' else self.btn_color_pressed
RoundedRectangle:
size: self.size
pos: self.pos
radius: [40]
# this is copied from style.kv to show the Button text
Color:
rgba: 1, 1, 1, 1Rectangle:
texture: self.texture
size: self.texture_size
pos: int(self.center_x - self.texture_size[0] / 2.), int(self.center_y - self.texture_size[1] / 2.)
# actually make an instance of the new MyButton class
MyButton:
btn_color_not_pressed: [1,0,0,1]
btn_color_pressed: [0,1,0,1]
text: 'Button Test'
The <-MyButton@Button>
creates a new class (MyButton
) that extends Button
. The prepended -
indicates that the default canvas
instructions for Button
are not to be used and the provided instructions are used instead. Those new Properties
can be changed in python code as usual. You can use a similar approach for the source
property.
Solution 2:
That brought me a step closer.
My problem now is that the colors only change the button itself or togglebutton-group, but only when you click on them. It only reacts to the new colors when activated (button og group).
The design is not updated
I tried the solution with the -
but it made no difference
main.py
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.factory import Factory
kivy.require("1.11.1")
classController(BoxLayout):
def__init__(self):
super(Controller, self).__init__()
ToggleButtonBehavior.allow_no_selection = Falsedefchange_button_color(self,theme):
if theme == "red":
Factory.My_tgl_btn.btn_color_pressed = (1,0,0,.7)
Factory.My_tgl_btn.btn_color_not_pressed = (1,0,0,.5)
else: # theme == "blue":
Factory.My_tgl_btn.btn_color_pressed = (0,0,1,.7)
Factory.My_tgl_btn.btn_color_not_pressed = (0,0,1,.5)
classmainApp(App):
defbuild(self):
return Controller()
if __name__ == "__main__":
mainApp().run()
main.kv
#:set bg_color 1,1,1,.7#:set txt_color 0,0,0,1#:import Factory kivy.factory.Factory<Controller>BoxLayout:orientation:"vertical"background_color:1,1,1,.5background_normal:""Label:text:"THIS IS THE MAIN TEKST"color:txt_colorsize_hint_y:.7BoxLayout:size_hint_y:.15My_tgl_btn:text:"RED theme"group:1state:"down"on_press:root.change_button_color("red")on_release:root.change_button_color("red")My_tgl_btn:text:"Blue theme"group:1on_press:root.change_button_color("blue")on_release:root.change_button_color("blue")BoxLayout:size_hint_y:.15My_tgl_btn:text:"Option1"group:2state:"down"My_tgl_btn:text:"Option2"group:2state:"normal"<My_tgl_btn@ToggleButton>btn_color_pressed:1,0,0,.7btn_color_not_pressed:1,0,0,.5color:txt_colorbackground_color:0,0,0,0background_normal:""canvas.before:Color:rgba:self.btn_color_not_pressedifself.state=='normal'elseself.btn_color_pressedRoundedRectangle:size:self.sizepos:self.posradius: [40]
Solution 3:
Found a solution (here: Kivy: resetting toggle buttons to "normal" on re-entering screen)
It's kind'a ugly, but it works..
Give every button an id ... and then use on_enter
for each button and set and change the state.
In the code above it would mean:
on_enter:
button1.state = "down"
button1.state = "normal"
button2.state = "down"
button2.state = "normal"
button3.state = "down"
button3.state = "normal"
button4.state = "down"
button4.state = "normal"
It works ... but it is not pretty :|
Post a Comment for "How To Target Canvas.before In Kv"