KIVY: Changing line colour in Paint App - python

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

Related

Lines are not drawn in Kivy python

This is the code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color
from kivy.graphics import Line
class MainWidget(Widget):
v_l_s=.1
v_l_n=7
Vertical_lines=[]
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.init_vertical_lines()
def on_size(self,*args):
self.update_vertical_lines()
def init_vertical_lines(self):
for num in range(0,self.v_l_n):
self.Vertical_lines.append(Line())
def update_vertical_lines(self):
cener_x=int(self.width/2)
before_lines=-(int(self.width/2))
line_x=cener_x+before_lines*self.v_l_s
for numb in range(0,self.v_l_n):
with self.canvas:
self.Vertical_lines[numb].points=[line_x,0,line_x,self.height]
before_lines+=1
class GameApp(App):
def build(self):
return MainWidget()
GameApp().run()
This code should return 7 vertical lines but it is showing nothing. What should I do to solve it ?(Note-An error is coming in publishing the question so don't care about this Note)
When you initially create the Line() instance, you are not doing in a canvas context. Just add with self.canvas: to the init_vertical_lines() method:
def init_vertical_lines(self):
with self.canvas:
for num in range(0, self.v_l_n):
self.Vertical_lines.append(Line())
Your code will then draw the 7 lines, but they are all in the same place (that's a different issue).

How to use different font weights for same font in Kivy

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

Kivy v1.9.1 canvas.clear() not working as expected

I'm not really sure as to why the canvas isn't clearing.
The first build(self) implementation that has the parent variable is the one that works. The only thing I see different is that the second implementation is adding the Button widget to the MyPaintWidget instead of both of those widgets getting added to a default Widget class.
Very new to kivy i'm semi-familiar with python. I'd love an explanation.
from random import random
import kivy
kivy.require('1.9.1')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color, Ellipse, Line
'''
class LoginScreen(GridLayout):
def __init__(self, **kwargs):
super(LoginScreen, self).__init__(**kwargs)
self.cols=2
self.add_widget(Label(text='User Name'))
self.username=TextInput(multiline=False)a
self.add_widget(self.username)
self.add_widget(Label(text='password'))
self.password=TextInput(password=True, multiline=False)
self.add_widget(self.password)
class MainApp(App):
def build(self):
return LoginScreen()
'''
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
color = (random(), 1, 1)
with self.canvas:
Color(*color)
d = 30.
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
touch.ud['line'] = Line(points=(touch.x, touch.y))
print(touch)
def on_touch_move(self, touch):
touch.ud['line'].points += [touch.x, touch.y]
class MyPaintApp(App):
#WHY ARE THESE TWO IMPLEMENTATIONS OF BUILD SO DIFFERENT?????
'''
def build(self):
parent = Widget()
self.painter = MyPaintWidget()
clearbtn = Button(text='Clear')
clearbtn.bind(on_release=self.clear_canvas)
parent.add_widget(self.painter)
parent.add_widget(clearbtn)
return parent
'''
def build(self):
self.painter = MyPaintWidget()
clearbtn = Button(text='Clear')
clearbtn.bind(on_release=self.clear_canvas)
self.painter.add_widget(clearbtn)
return self.painter
def clear_canvas(self, obj):
self.painter.canvas.clear()
if __name__ == '__main__':
MyPaintApp().run()
Touches are dispatched down the widget tree, they enter at the root widget which must pass the touch down to its children (or fail to do so, if it wants).
Your MyPaintWidget class overrides on_touch_down but fails to pass the touch to its children, so the Button never receives the touch and never gets a chance to become pressed.
Add return super(MyPaintWidget, self).on_touch_down(touch) to the MyPaintWidget.on_touch_down to call the parent class method that automatically handles this for you.

Kivy - First Widget of Class not getting color

I have some simple code below that is just creating some rectangles with a color assigned to them, and then storing them into a FloatLayout. For some reason, the very first rectangle 'Brick' that I create, doesnt get a color, but all subsequent ones do. I have issues with my game also where when another widget collides with a brick, it updates the attributes of the brick to its left, and not itself. I think the two issues are related.
What is going on with the first instance of Brick (brick1) that is being added to the FloatLayout that it doesnt get the color created?
import kivy
kivy.require('1.10.0')
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.properties import NumericProperty, ReferenceListProperty
from kivy.clock import Clock
from kivy.graphics import Rectangle, Ellipse, Color
from kivy.uix.floatlayout import FloatLayout
from kivy.vector import Vector
from kivy.utils import get_color_from_hex
import random
from kivy.config import Config
Window.size = (300,600)
class Brick(Widget):
def __init__(self, xloc, yloc, **kwargs):
super().__init__(**kwargs)
with self.canvas:
self.size = (25,25)
self.x = xloc
self.y = yloc
self.pos = (self.x,self.y)
self.body = Rectangle(pos=self.pos,size = self.size)
self.c = Color(1,0,1)
class Game(Widget):
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.brick_container = FloatLayout(size = (25,25))
brick1 = Brick(50,100)
brick2 = Brick(100,100)
self.brick_container.add_widget(brick1)
self.brick_container.add_widget(brick2)
self.add_widget(self.brick_container)
def update(self,dt):
self.name = 'nothing'
class MyApp(App):
def build(self):
game = Game()
Clock.schedule_interval(game.update, 1.0/60.0)
return game
if __name__ == '__main__':
MyApp().run()
You have to set the color first and then the rectangle
class Brick(Widget):
def __init__(self, xloc, yloc, **kwargs):
super().__init__(**kwargs)
self.size = (25,25)
self.pos = (xloc , yloc)
with self.canvas:
self.c = Color(1,0,1)
self.body = Rectangle(pos=self.pos,size = self.size)
According to the docs when using a Drawing Instruction, use the color set above.
Drawing instructions
Drawing instructions range from very simple
ones, like drawing a line or a polygon, to more complex ones, like
meshes or bezier curves:
with self.canvas:
# draw a line using the default color
Line(points=(x1, y1, x2, y2, x3, y3))
# lets draw a semi-transparent red square
Color(1, 0, 0, .5, mode='rgba')
Rectangle(pos=self.pos, size=self.size)
For that reason in your original code the first Brick used the color by default(white), and the others if they had the correct color.

Why does right-clicking create an orange dot in the center of the circle?

Why does the first widget example in kivy lead to an orange circle in the middle of the yellow one when you right click on the canvas and a pure yellow one when you left click?
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
Color(1, 1, 0)
d = 30.
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
class MyPaintApp(App):
def build(self):
return MyPaintWidget()
if __name__ == '__main__':
MyPaintApp().run()
To disable multi-touch emulation, add this to your source file containing your main function, before any other kivy modules are imported:
from kivy.config import Config
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
It's multitouch emulation, you can see how to disable it here
http://kivy.org/docs/api-kivy.input.providers.mouse.html

Categories