How to align a rectangle using kivy? - python

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

Related

KivyLauncher: Incorret imaging on phone screen

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

How to update a texture from array in Kivy?

I'm new to Kivy, but have watched the tutorials. I want to have a widget containing a texture or image generated from an array, which will change at each frame. See below for what I currently have. Current behaviour is wrong when I resize the window - I think that the old Rectangle is never being deleted, but I can't see how to do that. It also shows the same image in a default (100,100) view at the bottom left of the main window. What do I need to change to achieve the desired behaviour, and not get artifacts when resizing the window?
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.layout import Layout
from kivy.graphics import Rectangle
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import numpy as np
import random
class MainDisplay(Layout):
tex = ObjectProperty(None)
def __init__(self, **kwargs):
super(MainDisplay, self).__init__(**kwargs)
Clock.schedule_once(self.texture_init, 0)
def texture_init(self, instance):
self.tex = Texture.create()
def update(self, dt):
size = 64 * 64 * 3
buf = np.array([int(random.random() * x * 255 / size) for x in range(size)])
print('update', max(buf), min(buf), np.mean(buf))
# then blit the buffer
self.tex.blit_buffer(buf.tostring(), colorfmt='bgr', bufferfmt='ubyte')
print('end update')
print(self.canvas)
print(self.size, self.pos, self, self.parent)
with self.canvas:
Rectangle(texture=self.tex, size=(self.width / 2, self.height / 2), pos=(self.center_x / 2, self.center_y / 2))
class MainWindow(BoxLayout):
md = ObjectProperty(None)
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
def update(self, dt):
self.md.update(dt)
class ProtoApp(App):
def build(self):
mainWindow = MainWindow()
Clock.schedule_interval(mainWindow.update, 1.0/10.0)
return mainWindow
if __name__ == "__main__":
ProtoApp().run()
with the proto.kv file:
<MainWindow>:
md: md
MainDisplay:
id: md
size_hint: (0.5, 0.5)
Thanks in advance for your help!
Problem
Whenever the window is resized, it is creating new rectangle and leaving traces of the previous one.
Solution
Use the canvas's built-in function, clear()
Snippets
def update(self, dt):
size = 64 * 64 * 3
buf = np.array([int(random.random() * x * 255 / size) for x in range(size)])
# then blit the buffer
self.tex.blit_buffer(buf.tostring(), colorfmt='bgr', bufferfmt='ubyte')
with self.canvas:
self.rect = Rectangle(texture=self.tex, size=(self.width / 2, self.height / 2),
pos=(self.center_x / 2, self.center_y / 2))
self.bind(pos=self.update_rect, size=self.update_rect)
def update_rect(self, *args):
self.canvas.clear()
self.rect.pos = self.pos
self.rect.size = self.size

Kivy: Coordinates

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

Trouble with Kivy Python? Function error and image error

I am trying to use Kivy to build an app.
Here is the code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line
from kivy.core.window import Window
class Background_Animation(Widget):
def __init__(self, imageStr, **kwargs):
super(Background_Animation, self).__init__(**kwargs)
self.__init__= __init__(self, imageStr, **kwargs)
with self.canvas :
self.size= (Window.width * 0.002 * 25, Window.height *0.002 * 25 )
# bind the fbo to the current opengl context
self.bind(pos == self.update_graphics_pos)
# x center position
self.x = self.center_x
# declare the image
imageStr= Image("~/Downloads/psychTREE.jpg", **kwargs)
# y center position
self.y = self.center_y
self.pos= (self.x, self.y)
self.image= self.pos
return image
def build(self):
self.build = build
run = __init__(self, imageStr, **kwargs)
return run
if __name__ == "__main__" :
build(self, imageStr, **kwargs).run()
When I try to run the code, it says name "build" is not defined . Any ideas on how to solve this problem? Also, how would I make the image appear in the gui?

Python Kivy widget animation

I've posted similar topic recently, but this time I'll try to be more clear and specific. My problem is that widgets in Kivy aren't animating as they are expected to. Here's some example code, why are scatters better to animate than widgets:
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.animation import Animation
from kivy.graphics import Color, Rectangle
class ExampleWidget(Widget):
def __init__(self, **kwargs):
super(ExampleWidget, self).__init__(**kwargs)
self.size = (100,100)
self.pos = (100,100)
with self.canvas:
Color(1,0,0)
self.texture = Rectangle(size=self.size, pos=self.pos)
def on_pos(self, obj, value):
try: self.texture.pos = value
except: pass
class ExampleScatterTexture(Widget):
def __init__(self, **kwargs):
super(ExampleScatterTexture, self).__init__(**kwargs)
with self.canvas:
Color(0,1,0)
texture = Rectangle(size=self.size, pos=self.pos)
class ExampleScatter(Scatter):
def __init__(self, **kwargs):
super(ExampleScatter, self).__init__(**kwargs)
self.do_rotation = False
self.do_scale = False
self.do_translation = False
self.size = (100,100)
self.pos = (100,300)
texture = ExampleScatterTexture(size=self.size)
self.add_widget(texture)
class ExampleScreen(Widget):
def __init__(self, **kwargs):
super(ExampleScreen, self).__init__(**kwargs)
self.size = Window.size
example_widget = ExampleWidget()
self.add_widget(example_widget)
example_scatter = ExampleScatter()
self.add_widget(example_scatter)
#SCATTER IS GREEN, WIDGET IS RED
example_widget_animation = Animation(pos=(300,100), duration=2., t='in_bounce') + Animation(pos=(100,100), duration=2., t='in_bounce')
example_scatter_animation = Animation(pos=(300,300), duration=2., t='in_bounce') + Animation(pos=(100,300), duration=2., t='in_bounce')
example_widget_animation.repeat = True
example_scatter_animation.repeat = True
example_widget_animation.start(example_widget)
example_scatter_animation.start(example_scatter)
class BadAnimationExample(App):
def build(self):
root = ExampleScreen()
return root
if __name__ == "__main__":
BadAnimationExample().run()
As you can see, the widget animation is executed very fast and then there comes a pause, while scatter animation is very much like we expect it to be. My problem is that when I have my finger on the scatters all my on_touch_move() functions aren't working. Is there any solution?
Ok, I fixed the problem. I used my on_touch_move() method in the child widget class and the solution is to use it in the parent widget. Then there is no problem with scatter selection.

Categories