How to use different font weights for same font in Kivy - python

I was experimenting on Kivy and encountered a problem. I can easily change my label font using [font=font.ttf]Some text[/font], but noticed that I can't change font's weight. For example I have Helvetica Neue font on my computer, which can be Regular, Thin, UltraThin, etc. How am I supposed to change font's weight? Am I going to modify my HelveticaNeue.ttc file, because I didn't find anything helpful in kivy documentation?
Here is my code:
from random import random
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.animation import Animation
from kivy.graphics import Color
class MyApp(App):
def on_touch_down(self, instance, touch):
color = Color(random(), 1, 1, mode='hsv').rgba
anim = Animation(font_size=300, color=color, duration=0.1)
anim.start(self.root)
def on_touch_up(self, instance, touch):
color = Color(random(), 1, 1, mode='hsv').rgba
anim = Animation(font_size=200, color=color, duration=0.1)
anim.start(self.root)
def build(self):
# Here I have changed font
return Label(
font_size=200,
text='[font=HelveticaNeue.ttc]text[/font]',
markup=True,
on_touch_down=self.on_touch_down,
on_touch_up=self.on_touch_up
)
if __name__ == '__main__':
MyApp().run()

Related

How to center text in kivy

I am trying to center text in kivy. I tried using halign="center" like so:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import CoreLabel
from kivy.graphics import Rectangle, Color
from kivy.core.window import Window
class MyWidget(Widget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.clearcolor = (1, 1, 1, 1)
self.canvas.clear()
with self.canvas:
Color(0, 0, 0, 1)
label = CoreLabel(text="Text", font_size=50, halign="center")
label.refresh()
text = label.texture
Rectangle(size=text.size, pos=(865, 30), texture=text)
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == "__main__":
MyApp().run()
But that doesn't center the text around the given position (it is still left aligned). If I change the length of the text (and therefore its size), its position doesn't change, even though I want it to.
Try adding
label = CoreLabel(halign='center',valign='center')

How to fix the length of a line in kivy

As you all know kivy Line take points with (x1,y1.x2,y2,x3,y3). I want to create a geometric compass like it is in here. Considering the compass here I created a basic framework of this, which doesn't seems to be good enough.. (though isn't even close to match the compass there but is just the basic idea)
import kivy
from kivy.uix.widget import Widget
from kivy.uix.widget import Canvas
from kivy.graphics import Color
from kivy.graphics import Line
from kivy.uix.floatlayout import FloatLayout
from kivymd.app import MDApp
from kivy.uix.button import Button
from kivymd.uix.card import MDCard
class Main(FloatLayout):
def __init__(self,**kwargs):
super(Main, self).__init__(**kwargs)
self.my_widget = Widget(size_hint= (0.6,0.6),pos_hint = {'x':0.5,'top' : 0.8})
self.add_widget(self.my_widget)
with self.my_widget.canvas:
Color(rgba = (0,0,0,1))
def on_touch_downah(self,touch):
self.line = Line(points = (touch.x,touch.y),width = 4)
self.canvas.add(self.line)
def on_touch_moveah(self,touch):
self.line.points += touch.x,touch.y
self.my_widget.bind(on_touch_down=on_touch_downah)
self.my_widget.bind(on_touch_move=on_touch_moveah)
def on_touch_downeh(self, touch):
self.x_ = touch.x
self.y_ = touch.y
self.lines = Line(points=(touch.x,touch.y),width = 5)
self.canvas.add(self.lines)
def on_touch_moveeh(self, touch):
self.x2 = self.x_ + 0.1
self.y2 = self.y_ + 0.1
self.lines.points = (self.x_,self.y_,touch.x,touch.y,touch.x,touch.y)
self.my_widget.bind(on_touch_down=on_touch_downeh)
self.my_widget.bind(on_touch_move=on_touch_moveeh)
class Mysapp(MDApp):
def build(self):
return Main()
Mysapp().run()
It is just a framework but the only problem here is the length of the straight _line is not getting fixed, meaning it keep changing because of x3,y3. Is there any way to fix the length of this line so that under no circumstances its length would get modified but it should still be able to change its position?
Or is there any better widget for this purpose other than the circle widget? I want the user to be able to create curves and arcs as well as circles therefore can't switch to circle widget. The user should be able to use it just as the geometric compass as you can see the provided link..

On Kivy's Clock, I want Change the Label color

I want to change text color by passing the time.
I use Python and kivy.
This is my code.In this code, only a label come on.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock
import random
class MyLabel(Label):
def callback(self, *arg):
self.evt = Clock.schedule_interval(self.callback, 1)
def on_value(self, *arg):
self.parent.lbl.color = random.choice(['red','blue','black'])
class MyApp(App):
def build(self):
layout=BoxLayout()
layout.lbl = Label(text='NESIA')
layout.add_widget(layout.lbl)
return layout
MyApp().run()
`
You never call the on_value() method you define. What you can do is use Clock.schedule_interval() when you build the app, passing in the method that changes the label's colour and the interval in which you want it to be called like so:
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
import random
class MyLabel(Label):
def change_color(self, *args):
r, g, b = random.choice([[1, 0, 0],[0,0,1],[ 1, 1, 1]])
self.color = [r, g, b, 1]
class MyApp(App):
def build(self):
layout = BoxLayout()
label = MyLabel(text='NESIA')
Clock.schedule_interval(label.change_color, 1)
layout.add_widget(label)
return layout
MyApp().run()
This is assuming what you want is to have a label with the text NESIA whose colour is randomly set to red, blue, or black every second. Note that it's possible that random.choice() returns the same colour twice in a row, meaning it will look like it's not changing for however many seconds that happens for.

KIVY: Changing line colour in Paint App

How can I change line color in the kivy Paint app that I have made. I am able to change width of line, but I couldn't find anything for changing color of line.
My code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Line
class DrawRandom(Widget):
def on_touch_down(self, touch):
with self.canvas:
touch.ud["line"]=Line(points=(touch.x,touch.y),width=5)
def on_touch_move(self, touch):
touch.ud["line"].points += (touch.x, touch.y)
class PaintApp(App):
def build(self):
return DrawRandom()
if __name__ == "__main__":
PaintApp().run()
You simply add Color to your canvas.
In your imports import Color too.
from kivy.graphics import Line, Color
And in your Painter class add Color to canvas. In this example I try red.
Its rgba values.
def on_touch_down(self, touch):
with self.canvas:
Color(1,0,0,1)
touch.ud["line"] = Line( points = (touch.x, touch.y))

Set Background Image or Colour Rectangle to a Widget in GridLayout

Problem in hand is that i have a screen where i have created 4 widgets under gridlayout . Widget one is a custom widget which have a boxlayout and have 2 images and a button .
and other 3 widgets are simple buttons
Now i want to have a background image or coloured rectangle to the 1st widget but image is getting drawn at position 0,0 . I am trying to use canvas instructions to create a rectangle or Border Image but seems gridlayout shows the widget position as 0,0 and hence it created the rectangle at 0,0 . please see the code below :
Any ideas how to fix this and create rectangle as at the border of widget 1?
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen,FallOutTransition
from kivy.uix.image import Image
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.graphics import BorderImage
from kivy.graphics import Color, Rectangle ,Line
################# Images ######################
S = Image(source='images/Sti.png')
L = 'images/spinnin.gif'
################# Images ######################
class CButtonW(BoxLayout):
def __init__(self, **kwargs):
print "init --> CButton self.pos is ",self.pos
super(CButtonW, self).__init__(**kwargs)
self.orientation = 'vertical'
with self.canvas.before:
Color(1, 1, 0, 1, mode='rgba')
Rectangle(pos=self.pos,size=self.size)
BorderImage(
border=(10, 10, 10, 10),
source='images/tex.png')
self.add_widget(S)
self.add_widget(Button(text="Button 1"))
self.add_widget(Image(source=L))
class LevelScreen(Screen,GridLayout):
def __init__(self, **kwargs):
super(LevelScreen, self).__init__(**kwargs)
with self.canvas:
Line(points=(10, 10, 20, 30, 40, 50))
Color(1, 0, 1, 1, mode='rgba')
Rectangle(pos=self.pos, size=Window.size)
self.layout = GridLayout(cols=3,spacing=1,padding=10)
self.Button1 = CButtonW(id='1',text='Level 1')
self.Button2 = Button(id='2',text='Level 2')
self.Button3 = Button(id='3',text='Level 3')
self.Button4 = Button(id='4',text='Level 4')
self.layout.add_widget(self.Button1)
self.layout.add_widget(self.Button2)
self.layout.add_widget(self.Button3)
self.layout.add_widget(self.Button4)
LevelScreen.cols=3
LevelScreen.add_widget(self,self.layout)
print "position of 1st button is ",self.Button1.pos
print "position of 2 button is ",self.Button2.pos
# App Class
class MyJBApp(App):
def build(self):
sm = ScreenManager(transition= FallOutTransition())
sm.add_widget(LevelScreen(name='level'))
return sm
if __name__ == '__main__':
MyJBApp().run()
Your canvas instructions are drawn before the CButtonW is positioned by its layout, so at that point it's still in its default position of 0, 0.
You can fix it by adding code to reposition the instructions when the widget's position or size changes. The easiest way is to just use kv language in the first place, which will automatically create the relevant bindings, but you can also bind to pos or size in python, or use the on_propertyname events associated with their changes.

Categories