I want to draw image (*.png file) at FlayoutBox, on pc is result OK, after using KivyLauncher is on phone screen only white square. I tested two variants for drawing (draw_img_cnv and draw_img_wdg), but both results are bad.
Cann you explain me:
why is result white square on phone screen,
why draw_img_wdg isn't centered on pc,
how is diferent between both solutions?
Thank You!
from kivy.app import App
from kivy.graphics import Color, Rectangle, Ellipse
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.image import Image
import math
class Screen(FloatLayout):
def __init__(self, **kwargs):
super(Screen, self).__init__(**kwargs)
self.li_item = []
return
def draw_img_cnv(self):
size_img = (498, 498)
pos_img = (self.center[0] -size_img[0]/2.0, self.center[1] -size_img[1]/2.0)
with self.canvas:
Color(0, 1, 0, 1)
self.rect1 = Rectangle(size=self.size, pos=self.pos)
self. rose = Image(source="rose.png",pos=pos_img,size=size_img )
def draw_img_wdg(self):
size_img = (498, 498)
pos_img = (self.center[0] -size_img[0]/2.0, self.center[1] -size_img[1]/2.0)
with self.canvas:
Color(0, 1, 0, 1)
self.rect1 = Rectangle(size=self.size, pos=self.pos)
self. rose = Image(source="rose.png",pos=pos_img,size=size_img )
self.add_widget(self.rose)
return
class MainApp(App):
def build(self):
self.pos_sun = None
root = BoxLayout(orientation = 'vertical')
self.screen = Screen()
button = Button(text = 'Press',size_hint=(1, None), height=50)
root.add_widget(self.screen)
root.add_widget(button)
self.screen.draw_img_wdg()
self.screen.bind(size=self._update_rect, pos=self._update_rect)
return root
def _update_rect(self, instance, value):
self.screen.rect1.pos = instance.pos
self.screen.rect1.size = instance.size
self.screen.rose. pos = (instance.center[0] -498/2.0, \
instance.center[1] -498/2.0)
return
if __name__ == '__main__':
MainApp().run()
Related
Does anybody know the code to center align a rectangle using kivy but in a py file not kv. This is my code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle
from kivy.graphics import Color
class PongGame(Widget):
def __init__(self, **kwargs):
super(PongGame, self).__init__(**kwargs)
with self.canvas:
Color(255,255,255, mode='rgba')
self.rect = Rectangle(pos=(self.x + 50, self.y + 50), size=(50, 50))
# print(self.rect)
class PingyPong(App):
def build(self):
return PongGame()
# class MakeRectangle(Widget):
# def __init__(self, **kwargs):
# with self.canvas:
# # Color(255,255,255, mode='rgba')
# self.rect = Rectangle(pos=(200, 200), size=(50, 50))
# class PingPong(App):
# def build(self):
# return Rectangle()
if __name__ == '__main__':
PingyPong().run()
This is the output:
enter image description here
please help
You can do it by getting Window size and then create rectangle at the center
from kivy.core.window import Window
class PongGame(Widget):
def __init__(self, **kwargs):
super(PongGame, self).__init__(**kwargs)
with self.canvas:
Color(255,255,255, mode='rgba')
window_size = Window.size
size = 50
self.rect = Rectangle(pos=(window_size[0]/2-size/2, window_size[1]/2-size/2), size=(size, size))
print()
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.
I am trying to create a drawing app. I define the color of lines (red by default) using Kivy Canvas and the task is I need a button for example 'Green' that will change the color to green. I don't know actually understand how to do it.
What I tried is:
class PainterWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
self.color = Color(1, 0, 0, 1)
rad = 30
Ellipse(pos = (touch.x, touch.y), size = (rad / 2, rad / 2))
touch.ud['line'] = Line(points = (touch.x, touch.y), width = 15)
def on_touch_move(self, touch):
touch.ud['line'].points += touch.x, touch.y
def blue(self):
with self.canvas:
self.color = Color(0, 0, 1, 1)
class PaintApp(App):
def build(self):
parent = Widget()
self.painter = PainterWidget()
parent.add_widget(self.painter)
parent.add_widget(Button(text='Blue', size=(50, 50), pos=(0, 480), on_press = PainterWidget.blue))
return parent
But it doesn't work. I tried creating the color changing method in PaintApp doing something like PainterWidget.color = Color but it didn't work too.
Add a ListProperty, paint_color and assigned the default red color. When the Button is pressed change paint_color from red to blue. Please refer to the example below for details.
Example
main.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Ellipse, Line
from kivy.properties import ListProperty
class PainterWidget(Widget):
paint_color = ListProperty([1, 0, 0, 1])
def on_touch_down(self, touch):
with self.canvas:
Color(rgba=self.paint_color)
rad = 30
Ellipse(pos = (touch.x, touch.y), size = (rad / 2, rad / 2))
touch.ud['line'] = Line(points = (touch.x, touch.y), width = 15)
def on_touch_move(self, touch):
touch.ud['line'].points += touch.x, touch.y
def blue(self, instance):
self.paint_color = [0, 0, 1, 1]
class PaintApp(App):
def build(self):
parent = Widget()
self.painter = PainterWidget()
parent.add_widget(self.painter)
parent.add_widget(Button(text='Blue', size=(50, 50), pos=(0, 480), on_press=self.painter.blue))
return parent
if __name__ == "__main__":
PaintApp().run()
Output
In the following code i don't explain two problems:
If I use method __init__ --> Scene.canvas = None
I don't underestand to relative position objects on image.
I wanted to obtain knowledges about coordinates system from Kivy Manual, but without success.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.graphics import Ellipse
class Scene(Widget):
"""
def __init__(self):
self.x = 0
self.y = 100
self.dir = 1
"""
def set_par(self):
self.x = 0
self.y = 100
self.dir = 1
def create_ball(self):
with self.canvas:
Ellipse(pos = (0,0), size = (40, 40))
img = Image(pos = (0,0), source = 'image1.png') # square 40x40pixels
self.add_widget(img)
class SceneApp(App):
def build(self):
scene = Scene()
scene.create_ball()
return scene
if __name__ == '__main__':
SceneApp().run()
Printscreen form my code:
You did not call super() in your __init__ method. So Widget's __init__ method just get completely overrited.
Then use FloatLayout instead of Widget
You can to do something like this:
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import Ellipse
Window.size = (300, 300)
class Scene(FloatLayout):
def __init__(self, **kwargs):
super(Scene,self).__init__(**kwargs)
self.size = 300,300
def create_ball(self):
img = Image(pos = (-130, -130), source = 'image1.png') # square 40x40pixels
self.add_widget(img)
with self.canvas:
Ellipse(pos = (0,0), size = (40, 40))
class SceneApp(App):
def build(self):
scene = Scene()
scene.create_ball()
return scene
if __name__ == '__main__':
SceneApp().run()
i want to b able to draw only in the white area (the recangle area) for example if your trying to draw behind the buttons or over the label it wont draw. is it possible? i need it for my project in school, i need to be able to draw only in the white area so the paint wont cover the label for example or not to be able drawing under the buttons
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.graphics import Color, Rectangle, Line
from kivy.uix.stencilview import StencilView
from kivy.core.window import Window
import socket
import sys
import os
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from functools import partial
class MyPaintWidget(Widget):
lineSize = 5
def on_touch_down(self, touch):
with self.canvas:
touch.ud['Line'] = Line(points=(touch.x, touch.y), width=self.lineSize)
def on_touch_move(self, touch):
touch.ud['Line'].points += [touch.x, touch.y]
class MyPaintApp(App):
def build(self):
self.parent = Widget()
self.painter=MyPaintWidget(size=(695,510),pos=(100,50))
with self.painter.canvas:
Rectangle(pos=(100,50), size=(695,510))
with open("Send_word.txt",'r') as fr:
word_lable = Label(text = "Your word is " + fr.read(),font_size='30sp',pos = (400,530))
self.parent.add_widget(word_lable)
finishbtn = Button(text='finish',pos=(0, 0),size = (100,150))#finish button position and text
finishbtn.bind(on_release=self.finish)#finish button onclick
erasebtn = Button(text = "Erasor",pos=(0,150),size =(100,150))#erasor button position and text
erasebtn.bind(on_release=self.black)
redbtn = Button(text = "Red",background_color=(255,0,0,1.0),pos=(100, 0), size=(100,50))
redbtn.bind(on_release=self.red)
bluebtn = Button(text = "Blue",background_color=(0,0,255,1.0),pos=(200, 0), size=(100,50))
bluebtn.bind(on_release=self.blue)
greenbtn = Button(text = "Green",background_color=(0,255,0,1.0),pos=(300, 0), size=(100,50))
greenbtn.bind(on_release=self.green)
whitebtn = Button(text = "Black",pos=(400, 0), size=(100,50))
whitebtn.bind(on_release=self.white)
yellowbtn = Button(text = "Yellow",background_color=(255,255,0,1.0),pos=(500, 0), size=(100,50))
yellowbtn.bind(on_release=self.yellow)
lightbluebtn = Button(text = "L.Blue",background_color=(0,255,255,1.0),pos=(600, 0), size=(100,50))
lightbluebtn.bind(on_release=self.lightblue)
purplebtn = Button(text = "Purple", size=(100,50),background_color=(148,0,211,1.0),pos=(700,0))
purplebtn.bind(on_release=self.purple)
sizeupbtn = Button(text = "SizeUp",pos=(0, 300),size = (100,150))
sizeupbtn.bind(on_release=self.SizeUp)
sizedowmbtn = Button(text = "SizeDown",pos=(0, 450),size = (100,150))
sizedowmbtn.bind(on_release=self.SizeDown)
self.parent.add_widget(self.painter)
#self.parent.add_widget(word_lable())
self.parent.add_widget(finishbtn)
self.parent.add_widget(redbtn)
self.parent.add_widget(bluebtn)
self.parent.add_widget(greenbtn)
self.parent.add_widget(whitebtn)
self.parent.add_widget(yellowbtn)
self.parent.add_widget(erasebtn)
self.parent.add_widget(lightbluebtn)
self.parent.add_widget(purplebtn)
self.parent.add_widget(sizeupbtn)
self.parent.add_widget(sizedowmbtn)
return self.parent
def finish(self,obj):
self.painter.export_to_png("screenshot.png")
sexi = open("Send_word.txt",'r').read()
print repr(sexi)
send_file(sexi)
def red(self,obj):
with self.painter.canvas:
Color(1,0,0)
def blue(self,obj):
with self.painter.canvas:
Color(0,0,1)
def green(self,obj):
with self.painter.canvas:
Color(0,1,0)
def white(self,obj):
with self.painter.canvas:
Color(0,0,0)
def yellow(self,obj):
with self.painter.canvas:
Color(1,1,0)
def black(self,obj):
with self.painter.canvas:
Color(1,1,1)
def lightblue(self,obj):
with self.painter.canvas:
Color(0,1,1)
def purple(self,obj):
with self.painter.canvas:
Color(1,0,1)
def SizeUp(self,obj):
if(self.painter.lineSize <100):
self.painter.lineSize += 5
def SizeDown(self,obj):
if(self.painter.lineSize >1):
self.painter.lineSize -= 5
if __name__ == '__main__':
MyPaintApp().run()
You can do that the easy way and the hard way. The easy way is using StencilView as a widget, which has a nice demo.
The harder way is using the Stencil directly and target only specific areas of the widget's canvas.