kivy canvas doesn't shows - python

I'm trying to have a white background in window and I'm using Kivy modules and Kv language but the background still black.
main.py :
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
class MyUI(FloatLayout):
pass
class MyApp(App):
def build(self):
return MyUI()
def main():
MyApp().run()
if __name__ == '__main__':
main()
my.kv :
<MyUI>:
canvas:
Color:
rgba: 1,1,1,1

Color instructions are applied to shapes that you draw, e.g. if you write the following:
<MyUI>:
canvas:
Color:
rgba: 1,1,1,1
Rectangle:
pos: self.pos
size: self.size
now you will see a white Rectangle filling the screen (as that's what its pos and size are set to do).

Related

Python kivy position of the Label moves when resizing screen

I'm making an app in python kivy and in my tacscreen I have a draggable Image and an Label, whenever I drag my draggable Image my label drags with it as well. The position of the label is just below the draggable Image. The problem that I'm facing is whenever I resize my window and drag the image the label goes from this to this the space between the Image and the label is too much. How can I fix this? I want the label to always be like how it is in the first screenshot even after I resize the screen and drag. Below is my code. I have been trying to find a solution to this for a months now. I really appreciate any help. Thanks!
main.py
from kivy.properties import BooleanProperty
from kivy.properties import ObjectProperty
from kivy.metrics import dp
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
from kivy.uix.behaviors import DragBehavior
from kivy.uix.image import Image
class DragImage1(DragBehavior, Image):
dragging = BooleanProperty(False)
drag_label = ObjectProperty()
def on_touch_move(self, touch):
if touch.grab_current is self:
self.drag_label.pos = self.x, self.y - dp(300)
return super().on_touch_move(touch)
def on_touch_up(self, touch):
uid = self._get_uid()
if uid in touch.ud:
# do something on drop
print(self.source, 'dropped at', touch.x, touch.y)
return super(DragImage1, self).on_touch_up(touch)
class TacScreen(Screen):
Pass
GUI = Builder.load_file("main.kv")
class MainApp(App):
def build(self):
return GUI
def change_screen(self, screen_name, *args):
self.root.current = screen_name
MainApp().run()
main.kv
#:include tacscreen.kv
ScreenManager:
id: screen_manager
TacScreen:
name: "tac_screen"
id: tac_screen
tacscreen.kv
<tacscreen>:
#:import utils kivy.utils
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: "Background.png"
DragImage1:
drag_label: per
pos: root.center_x - self.width/2, root.center_y - self.height/0.3
size_hint: 1, .1
source: "Image.png"
Label:
id: per
text: "Hello"
font_size: "20dp"
pos: root.center_x - self.width/2, root.center_y - self.height/1.2
You can modify your kv to do the positioning for you:
DragImage1:
id: di # added id for use by the Label
drag_label: per
pos: root.center_x - self.width/2, root.center_y - self.height/0.3
size_hint: 1, .1
source: "Image.png"
Label:
id: per
text: "Hello"
font_size: "20dp"
size_hint: None, None
size: self.texture_size # set size to just contain the text
pos: di.center_x - self.width/2, di.y - self.height # adjust postion based on the DragImage1
And, since kv is now handling the positioning, you should remove the on_touch_move() method from the DragImage1 class.
Note that this will handle positioning when resizing before dragging. But if you drag before resizing, then the resizing will revert the position to that defined in the kv.

How do I show the color of a label on a image in kivy?

I am new to kivy. I inserted a label on an image. But it doesn't show the color of the label. It only shows the text as shown in the image. If you can please tell me how to show the color of the label.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Money_Manager>:
Image:
source:'image4.png'
SmoothLabel:
text: "Hello[![enter image description here][1]][1] World"
size: 0.1,.1
rgb: (255,255,255)
<SmoothLabel#Label>
background_normal: ''
border_radius: [18]
canvas.before:
Color:
rgba: (255,255,255, 1)
RoundedRectangle:
size: .1,.1
pos: self.pos
radius: self.border_radius
""")
class Money_Manager(App, FloatLayout):
def build(self):
return self
Money_Manager().run()
Hey Did you mean you want to color the Hello World label from white to something else.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Money_Manager>:
Image:
source:'image4.png'
SmoothLabel:
text: "Hello World"
size: 0.1,.1
color: [255,100,0,1]
<SmoothLabel#Label>
background_normal: ''
border_radius: [18]
canvas.before:
Color:
rgba: (255,0,0, 1)
RoundedRectangle:
size: .1,.1
pos: self.pos
radius: self.border_radius
""")
class Money_Manager(App, FloatLayout):
def build(self):
return self
Money_Manager().run()
With little change in your code line
rgb: (255,255,255)
to
color: [255,100,0,1]
I am able to colour it green. Is this what you want.

Advanced open and close animation for a button

The animation I currently have for opening and closing a button, is simply a sub button comes out from the main button and expands using size_hint. This animation simply enlarges the sublayout. I would like to 'unveil' the sublayout instead. What I mean by that, is to not mess with size_hint of the sub and instead of expanding itself, I want it to 'unveil' itself which makes for a much cleaner animation. Heres a link of a button animation that uses the same effect. https://codemyui.com/button-to-a-list-animation/.
In the linked animation, the bottom border goes down and reveals the list underneath, the same effect I want.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import *
from kivy.animation import Animation
from kivy.lang.builder import Builder
from kivy.uix.behaviors import *
from kivy.properties import *
Builder.load_string("""
<Root>
Button1:
size_hint: 0.2,0.1
pos_hint: {'top':0.9,'center_x':0.5}
canvas:
Color:
rgba: [0.4,0.4,0.4,1]
Rectangle
size: self.size
pos: self.pos
SubLayout:
pos_hint: {'top':1,'center_x':0.5}
canvas:
Color:
rgba: [0.7,0.7,0.7,1]
Rectangle
size: self.size
pos: self.pos
Color:
rgba: [1,1,1,1]
Ellipse:
pos: self.pos
size: self.size
""")
class Root(FloatLayout):
pass
class Button1(ToggleButtonBehavior, FloatLayout):
def __init__(self,**kwargs):
super(Button1,self).__init__(**kwargs)
def on_state(self, *args):
if self.state == 'down':
anim = Animation(pos_hint={'top':0},d=0.2)
anim += Animation(size_hint=(2,2),d=0.2) #: expanding sublayout, how do I unveil instead?
anim.start(self.children[0])
else:
anim = Animation(size_hint=(1,1),d=0.2)
anim += Animation(pos_hint={'top':1},d=0.2)
anim.start(self.children[0])
class SubLayout(FloatLayout):
pass
class TestApp(App):
def build(self):
return Root()
if __name__ == '__main__':
TestApp().run()
As you can see, SubLayout expands and you can see the ellipse inside expanding with the button. What I would like is for the borders to move away, revealing whats underneath them while leaving the ellipse's size the same, which is the 'unveiling' effect. Any ideas on how to do this would be appreciated. Maybe something to do with an Fbo?

Kivy - Black Screen between transitions

I'm trying to copy this gif, which is done in Kivy (here's the link to the full page )
Just as I started, I noticed a black screen between transition (link to what it looks like so you don't have to copy-paste and run)
Why does that black screen appear?
EDIT: I must work without buttons.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
# Create both screens. Please note the root.manager.current: this is how
# you can control the ScreenManager from kv. Each screen has by default a
# property manager that gives you the instance of the ScreenManager used.
Builder.load_string("""
<MenuScreen>:
canvas.before:
Color:
rgba: 122,255,0,2
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'hello'
<SettingsScreen>:
canvas.before:
Color:
rgba: 0,255,0,2
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'hello'
""")
# Declare both screens
class MenuScreen(Screen):
def on_touch_down(self, touch):
sm.current = 'settings'
class SettingsScreen(Screen):
def on_touch_down(self, touch):
sm.current = 'menu'
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SettingsScreen(name='settings'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
EDIT: I've tried this but still not working
<sm>:
canvas:
Color:
rgb: (0, 255, 255)
Rectangle:
size: self.size
pos: self.pos
You are not supposed to use the Screen subclasses directly. Instead you must add a component first (e.g. Button or Layout), for example use RelativeLayout:
Builder.load_string("""
<MenuScreen>:
RelativeLayout:
canvas.before:
Color:
rgba: 122,255,0,2
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'hello'
<SettingsScreen>:
RelativeLayout:
canvas.before:
Color:
rgba: 0,255,0,2
Rectangle:
pos: self.pos
size: self.size
Label:
text: 'hello'
""")
That black area is a canvas of the screen manager. If you don't like it black, then you can paint it, just like you did with screens; or change transition type to NoTransition to hide it.
Also, you should consider building your screen manager inside that kv lang string.
Old, but in case anyone runs into this issue:
To clarify the vague responses in the comments, you need to paint your screen manager the same way you would paint a screen.
Example in kvlang:
ScreenManagement:
canvas.before:
Color:
rgba: 1,1,1,1
Rectangle:
size: self.size
pos: self.pos
id: screen_manager
transition: NoTransition()
Screen1:
Screen2:
Settings_:

Clean canvas in kivy language

You can call widget's canvas from kivy language using canvas[.before|.after] member like this.
<MyWidget>:
canvas:
Rectangle:
source: 'mylogo.png'
pos: self.pos
size: self.size
How can I clear the canvas before I put the instructions?
Use Clear:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
kv_string = '''
<MyWidget>:
canvas:
Color:
rgb: 0.1, 0.6, 0.3
Ellipse:
size: self.size
pos: self.pos
Clear
Color:
rgb: 0.6, 0.2, 0.1
Ellipse:
size: self.size
pos: self.center
'''
Builder.load_string(kv_string)
class MyWidget(Widget):
pass
class TestApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
TestApp().run()
In example above only one ellipse will be drawn since first one gets erased with Clear command. You can call it from Python using code like:
class SomeWidget(Widget):
def some_method(self):
self.canvas.clear()
with self.canvas:
# ...
i used
Window.clearcolor = (x,y,z,w)
and it works... so why use canvas?

Categories