change the background canvas kivy - python

I have a canvas background but I am trying to switch the back ground when a person his a correct button to move on to the next level. I am trying to do this all within one class. Is there a way to assign an image to a canvas rectangle and then on the press of a button the canvas image will change to a new source.
main.py
class MazeSolution(Screen):
def CheckDoor1(self):
if self.ids.door1.source == "correct":
print("correct")
self.ids.change.source = 's-curvee selection.png'
else:
print("incorrect")
main.kv
#:import utils kivy.utils
<MazeSolution>:
FloatLayout:
canvas:
Rectangle:
id: change
source: 'selection grass.png'
pos: self.pos
size: self.size
Button:
pos_hint: {"top": .8, "right": .75}
size_hint: .5, .1
text:
"Door 1"
source: "<random_name>"
id: door1
on_press:
root.CheckDoor1()

I don't think assigning ids within canvas instructions is supported. But you can accomplish the same thing by creating the Rectangle in python:
from kivy.app import App
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
class MazeSolution(Screen):
def __init__(self):
super(MazeSolution, self).__init__()
# make the Rectangle here and save a reference to it
with self.canvas.before:
self.rect = Rectangle(source='selection grass.png')
def on_pos(self, *args):
# update Rectangle position when MazeSolution position changes
self.rect.pos = self.pos
def on_size(self, *args):
# update Rectangle size when MazeSolution size changes
self.rect.size = self.size
def CheckDoor1(self):
if self.ids.door1.source == "correct":
print("correct")
# use the saved reference to change the background
self.rect.source = 's-curvee selection.png'
else:
print("incorrect")
Builder.load_string('''
<MazeSolution>:
FloatLayout:
Button:
pos_hint: {"top": .8, "right": .75}
size_hint: .5, .1
text:
"Door 1"
source: "correct"
id: door1
on_press:
root.CheckDoor1()
''')
class TestApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MazeSolution())
return sm
TestApp().run()
The on_pos() and on_size() methods perform the operations that kv would set up for you automatically, but must be set up manually since the Rectangle is not created in kv.

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 to handle clock module with multiple screens in Kivy?

I tried to move a ball around an origin (like the moon in its orbit around the earth). At first I created the ball object inside GameScreen. Then I got the AttributeError that my object does not have "move" attribute. So i created another widget called MainGame as a parent of the ball object. Now the error is gone but the ball does not actively moving. I could not figure out what i'm missing since I'm pretty new to Kivy. I guess it's about Clock module and my custom update function. All answers and helps are appreciated, thanks!
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.lang import Builder
import math
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.clock import Clock
class GameBall(Widget):
org_x, org_y = 300, 300
dist = 100
ang_deg = 0
pos_x = NumericProperty(org_x+dist)
pos_y = NumericProperty(org_y)
pos = ReferenceListProperty(pos_x, pos_y)
def move(self):
self.ang_deg += 5
self.ang_rad = math.radians(self.ang_deg)
self.pos_x, self.pos_y = self.org_x + self.dist*math.cos(self.ang_rad), self.org_y + self.dist*math.sin(self.ang_rad)
class MainGame(Widget):
game_ball = GameBall()
def update(self, dt):
self.game_ball.move()
class ScreenManagement(ScreenManager):
pass
class MenuScreen(Screen):
pass
class GameScreen(Screen):
pass
GUI = Builder.load_file("gui.kv")
class MobileGameApp(App):
def build(self):
game = MainGame()
Clock.schedule_interval(game.update, 1.0/60.0)
return GUI
if __name__ == "__main__":
MobileGameApp().run()
---- Kv file:
ScreenManagement:
MenuScreen:
GameScreen:
<MenuScreen>:
name: "menu_screen"
Button:
size_hint: .2, .2
pos: root.width/2 - self.width/2, root.height/2 - self.height/2
text: "Play Game"
on_release:
root.manager.transition.direction = "left"
root.manager.current = "game_screen"
<GameScreen>:
game_ball: main_game.game_ball
name: "game_screen"
Button:
size_hint: .2, .2
pos_hint: {'top': 1}
text: "Go to menu"
on_release:
root.manager.transition.direction = "right"
root.manager.current = "menu_screen"
MainGame:
id: main_game
GameBall:
id: game_ball
center: self.parent.center
canvas:
Ellipse:
size: 50, 50
pos: self.pos
Several problems with your code. One important thing I see in your code is creating new object instances when you actually want to reference existing instances:
game = MainGame()
and
game_ball = GameBall()
are creating new instances of MainGame and GameBall. Neither of those new instances are in your GUI, so any changes you make to those new instances will have no effect on your GUI.
So, you need to get references to the existing MainGame and GameBall. Those are the instances created by your kv file. One way to do that is to make the following changes to your code.
You can simplify GameBall as:
class GameBall(Widget):
org_x, org_y = 300, 300
dist = 100
ang_deg = 0
def move(self):
self.ang_deg += 5
self.ang_rad = math.radians(self.ang_deg)
self.pos = (self.org_x + self.dist*math.cos(self.ang_rad), self.org_y + self.dist*math.sin(self.ang_rad))
And MainGame can become:
class MainGame(Widget):
game_ball = ObjectProperty(None)
def update(self, dt):
self.game_ball.move()
And starting the animation now looks like:
class MobileGameApp(App):
def build(self):
Clock.schedule_once(self.start_updates)
return GUI
def start_updates(self, dt):
Clock.schedule_interval(self.root.get_screen('game_screen').ids.main_game.update, 1.0/60)
And then, to simplify accessing the GameBall, I added a game_ball to the kv as:
MainGame:
game_ball: game_ball
id: main_game
GameBall:
id: game_ball
center: self.parent.center
canvas:
Ellipse:
size: 50, 50
pos: self.pos

kivy - how to prepare app for touch events

I am developing an app using Kivy for Android and IOS, i haven't tried it on any mobile yet but i have been noticing that i need to add some sort off 'touch' events so the buttons, swipes and etc will work on a mobile touchscreen.
i've tried searching around for examples but i didn't exactly get the concept, and i was wondering what exactly do i need to do for it to be ready for touch events, i am thinking of making a 'swiping touch' to move between pages on both sides, what do i need to do to make this happen?
When you want to swipe through pages as you have mentioned. It could be a nice option to use PageLayout. Check the docs:https://kivy.org/doc/stable/api-kivy.uix.pagelayout.html
PageLayout is where you have several pages and you can swipe through them. It could be suitable for you.
Here is a very simple example.Where you will have three pages
PageLayout:
Button:
text: 'page1'
Button:
text: 'page2'
Button:
text: 'page3'
Here is a advanced pagelayout example from kv file. The pagelyout then consists of floatlayouts. But you could use other layouts too
<Example>:
PageLayout:
FloatLayout:
id: string1
canvas:
Color:
rgb:utils.get_color_from_hex("#2BFFFA")
Rectangle:
size: self.size
pos:self.pos
Image:
size_hint:.9,1
pos_hint:{"top": 1,"right": 1}
source: "string/str1.png"
FloatLayout:
canvas:
Color:
rgb:utils.get_color_from_hex("#39FF22")
Rectangle:
size: self.size
pos:self.pos
Image:
size_hint:.9,1
pos_hint:{"top": 1,"right": 1}
source: "string/str1_sol.png"
FloatLayout:
canvas:
Color:
rgb:utils.get_color_from_hex("#2BFFFA")
Rectangle:
size: self.size
pos:self.pos
Image:
size_hint:.9,1
pos_hint:{"top": 1,"right": 1}
source: "string/str2.png"
Notice that my main layout is a pagelayout and in the floatlayout I have floatlayouts. So now I have three pages to swipe through
Or you could use a screemanger to manage your screens. . And then you just have to click on a button and then you will automatically switch screens. Here is a example. This is better than pagelayouts.
import kivy
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
class ScreenOne(Screen):
def __init__ (self,**kwargs):
super (ScreenOne, self).__init__(**kwargs)
my_box1 = BoxLayout(orientation='vertical')
my_label1 = Label(text="BlaBlaBla on screen 1", font_size='24dp')
my_button1 = Button(text="Go to screen 2",size_hint_y=None, size_y=100)
my_button1.bind(on_press=self.changer)
my_box1.add_widget(my_label1)
my_box1.add_widget(my_button1)
self.add_widget(my_box1)
def changer(self,*args):
self.manager.current = 'screen2'
class ScreenTwo(Screen):
def __init__(self,**kwargs):
super (ScreenTwo,self).__init__(**kwargs)
my_box1 = BoxLayout(orientation='vertical')
my_label1 = Label(text="BlaBlaBla on screen 2",font_size='24dp')
my_button1 = Button(text="Go to screen 1",size_hint_y=None, size_y=100)
my_button1.bind(on_press=self.changer)
my_box1.add_widget(my_label1)
my_box1.add_widget(my_button1)
self.add_widget(my_box1)
def changer(self,*args):
self.manager.current = 'screen1'
class TestApp(App):
def build(self):
my_screenmanager = ScreenManager()
screen1 = ScreenOne(name='screen1')
screen2 = ScreenTwo(name='screen2')
my_screenmanager.add_widget(screen1)
my_screenmanager.add_widget(screen2)
return my_screenmanager
if __name__ == '__main__':
TestApp().run()

adding widget dynamically into kivy screen object

As far as I am aware, kv language is useful when making a static display, e.g. not when making game which need much widget's positioning during runtime. Here I try to make a simple game, but still need much positioning, so kv language is out of context for the widget, but not for the screen. I use screen to differentiate the main menu and game screen. But when I try to use 'add_widget' to insert my image, it always positioned at the middle of the window. Later I found out that the screen size is only 100x100.
Below are the only way that I can thought of, but still with no luck:
class HomeScreen(Screen):
pass
class GameScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation=Builder.load_file('ProjectSD.kv')
class ProjectSDApp(App):
def build(self):
A=presentation
A.screens[0].size=(Window.size)
A.screens[0].add_widget(Label(text='hello',font_Size=80,pos=(0,0)))
return A
if __name__=='__main__':
print(Window.size)
ProjectSDApp().run()
and my ProjectSD.kv file:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
HomeScreen:
GameScreen:
<Button>:
font_name:'attackofthecucumbers.ttf'
<HomeScreen>:
name:'home'
canvas:
Rectangle:
pos: self.pos
size: self.size
source: 'nature.jpg'
Label:
text: 'Monopoly GX'
font_name:'KBDunkTank.ttf'
font_size:100
size_hint:0.7,0.2
pos:root.width*0.15,root.height*0.70
Button:
on_release: app.root.current = "game"
text: 'Play Game'
font_size:root.width/20
size_hint:0.3,0.15
pos:root.width*0.35,root.height*0.45
Button:
on_release: app.stop()
text: 'exit'
font_size:root.width/20
size_hint:0.3,0.15
pos:root.width*0.35,root.height*0.20
<GameScreen>:
name:'game'
Button:
on_release: app.root.current = "home"
background_color: (1,0.15,0.2,0.8)
text: 'X'
font_size:root.width/40
size_hint:0.05,0.05
pos:root.width*0.95,root.height*0.95
Since there is no 'pos' method in screen object, I put my widget to position (0,0) manually.
The only way I found is just below:
https://kivyspacegame.wordpress.com/2014/08/10/tutorial-flappy-ship-part-2-build-simple-menus-and-animate-your-games-using-clock/
So my question is, if I use screen object from kivy's build in, how to achieve the same result? So I can still adding and remove widget as I want it later?
I'm not entirely clear on what you're asking; I don't see anywhere in your code where you are trying to add an Image to a Layout. You add a label to the middle and that works fine.
I think because you are creating screens without any layouts and not setting a default window size, that the screens just take up their minimum default size. You need to add a layout and fill it with stuff that has a defined size, or set a window size at the beginning e.g:
# window import
from kivy.core.window import Window
from kivy.utils import get_color_from_hex
Window.size = (1920/2,1080/2)
Window.clearcolor = get_color_from_hex('#000000') # black
Here is some code that creates your two Screens, and adds a draggable and a static Image at a position to a FloatLayout.
from kivy.app import App
from kivy.uix.screenmanager import (ScreenManager, Screen)
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.behaviors import DragBehavior
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
class HomeScreen(Screen):
pass
class GameScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class MovingImage(DragBehavior,Image):
pass
class DragLabel(DragBehavior, Label):
pass
class StaticImage(Image):
pass
class MyApp(App):
def build(self):
A = ScreenManagement()
A.current = 'game'
A.screens[1].ids.gamefloat.add_widget(MovingImage(size_hint = [0.3,0.3]))
A.screens[1].ids.gamefloat.add_widget(StaticImage(pos = (150,300)))
return A
if __name__=='__main__':
MyApp().run()
and the .kv file called myapp.kv
<ScreenManagement>:
HomeScreen:
GameScreen:
<Button>:
<HomeScreen>:
name:'home'
canvas:
Rectangle:
pos: self.pos
size: self.size
source: 'image.jpg'
Label:
text: 'Monopoly GX'
font_size:100
size_hint:0.7,0.2
pos:root.width*0.15,root.height*0.70
Button:
on_release: app.root.current = "game"
text: 'Play Game'
font_size:root.width/20
size_hint:0.3,0.15
pos:root.width*0.35,root.height*0.45
Button:
on_release: app.stop()
text: 'exit'
font_size:root.width/20
size_hint:0.3,0.15
pos:root.width*0.35,root.height*0.20
<GameScreen>:
name:'game'
FloatLayout:
id: gamefloat
Button:
on_release: app.root.current = "home"
background_color: (1,0.15,0.2,0.8)
text: 'X'
font_size:root.width/40
size_hint:0.05,0.05
pos:root.width*0.95,root.height*0.95
<MovingImage>:
drag_rectangle: self.x, self.y, self.width, self.height
drag_timeout: 1000000
drag_distance: 0
source: 'image.jpg'
<StaticImage>:
source: 'image.jpg'

How to unbind a property automatically binded in Kivy language?

The Kivy Language automatically creates internal binds in properties. For example, if we assign the position of the parent to the position of the child, then the position of the child is going to be updated automatically:
Widget:
Label:
pos: self.parent.pos
In this case, if we move the parent Widget, then the child is also going to move. How do I unbind the property pos from the child? I know how to unbind (properties)[http://kivy.org/docs/api-kivy.uix.widget.html#using-properties] that I bind myself but how do I unbind them if I don't know the name of the method it is bound.
Here is a small example to show what I mean. The Button Up moves the GridLayout to the top and Down to the Bottom. The Button Center center itself in the middle of the screen. My problem is that when I click Up or Down my Centered button is not anymore.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Example>:
GridLayout:
id: _box
cols: 3
size_hint: .7, .3
pos_hint: {'center_x': .5}
x: 0
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _box.y = 0
text: "Down"
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: self.center_y = root.height/2
text: "Out of the Grid"
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _box.top = root.height
text: "Up"
""")
class Example(FloatLayout):
pass
class ExampleApp(App):
def build(self):
return Example()
if __name__ == "__main__":
ExampleApp().run()
Why do I want to do that in any case? I am using an animations on the GridLayout that constantly updates the position. The normal position of the buttons should be inside the gridlayout but once in a while one of the buttons flies over the screen and come back to the same position. The problem is that I cannot make them fly while my gridlayout is also moving because the property is bound and as soon as the button try to fly it goes back to the grid. That also means that the binding is sometimes desirable. What I want is have control of the bind and unbind.
Comments don't seem to be working right now so I'll post this as a answer.
You already have a FloatLayout(your root widget). Use that instead of
creating a new FloatLayout.
Before removing the widget from the grid.
store it's size,
set size_hint to None, None
set pos_hint to position the widget in the center.
When adding the widget to grid do the reverse.
Here's your code with these fixes::
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Example>:
center_button: _center_button
center_widget: _center_widget
grid:_grid
GridLayout:
id: _grid
cols: 3
size_hint: .7, .3
pos_hint: {'center_x': .5}
x: 0
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _grid.y = 0
text: "Down"
Widget:
id: _center_widget
Button:
id: _center_button
pos: self.parent.pos
size: self.parent.size
on_press: root.centerize(*args)
text: "Out of the Grid"
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _grid.top = root.height
text: "Up"
""")
class Example(FloatLayout):
def centerize(self, instance):
if self.center_button.parent == self.center_widget:
_size = self.center_button.size
self.center_widget.remove_widget(self.center_button)
self.center_button.size_hint = (None, None)
self.add_widget(self.center_button)
self.center_button.pos_hint = {'center_x': .5, 'center_y':.5}
else:
self.remove_widget(self.center_button)
self.center_button.size_hint = (1, 1)
self.center_widget.add_widget(self.center_button)
self.center_button.size = self.center_widget.size
self.center_button.pos = self.center_widget.pos
class ExampleApp(App):
def build(self):
return Example()
if __name__ == "__main__":
ExampleApp().run()
Update 1:
If for whatever reason you still need to unbind the properties bound by kvlang you can do so using introspection to get a list of observers for the property. so for your case it would be something like this::
observers = self.center_widget.get_property_observers('pos')
print('list of observers before unbinding: {}'.format(observers))
for observer in observers:
self.center_widget.unbind(pos=observer)
print('list of observers after unbinding: {}'.format(self.center_widget.get_property_observers('pos')))
You would need to use the latest master for this. I should fore-warn you to be extremely careful with this though you'd need to reset the bindings set in kvlanguage, but then you loose the advantage of kv language... Only use this If you really understand what you are doing.
Following #qua-non suggestion, I am temporarily moving the child to another parent. It actually unbinds it, or maybe, rebinds it to the new parent. This is a partial solution because of whatever reason, it doesn't update the position automatically when I took it out of the GridLayout (i.e. when I press enter) and put it into the new parent. I need to press 'Up' (or 'Down') after the 'Out of the Box' button.
However, it does go back immediately. When you click again on the 'Out of the box' button the 2nd time, it goes back to its original position. This part works perfectly. And it continue obeying to its parent instructions.
In other words, it doesn't work immediately when I take out of the grid but it does when I put it back.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Example>:
center_button: _center_button
center_widget: _center_widget
float: _float
grid:_grid
GridLayout:
id: _grid
cols: 3
size_hint: .7, .3
pos_hint: {'center_x': .5}
x: 0
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _grid.y = 0
text: "Down"
Widget:
id: _center_widget
Button:
id: _center_button
pos: self.parent.pos
size: self.parent.size
on_press: root.centerize(*args)
text: "Out of the Grid"
Widget:
Button:
pos: self.parent.pos
size: self.parent.size
on_press: _grid.top = root.height
text: "Up"
FloatLayout:
id: _float
size_hint: None,None
""")
class Example(FloatLayout):
def centerize(self, instance):
if self.center_button.parent == self.center_widget:
self.center_widget.remove_widget(self.center_button)
self.float.add_widget(self.center_button)
self.float.size = self.center_button.size
self.float.x = self.center_button.x
self.float.center_y = self.center_y
else:
self.float.remove_widget(self.center_button)
self.center_widget.add_widget(self.center_button)
self.center_button.size = self.center_widget.size
self.center_button.pos = self.center_widget.pos
class ExampleApp(App):
def build(self):
return Example()
if __name__ == "__main__":
ExampleApp().run()
Here is something very similar to what I was trying. The difference is that I ended binding the properties manually so I can unbind them. Basically if I uncomment the line #pos: self.parent.pos of the 'out of the box' button, then I cannot unbind them unless I assign the Button to another parent as #qua-non suggested.
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
Builder.load_string("""
<Example>:
center_button: _center_button
GridLayout:
cols: 3
size_hint: .7, .3
pos_hint: {'center_x': .5}
Button:
on_press: self.parent.y = 0
text: "Down"
Widget:
Button:
id: _center_button
size: self.parent.size
#pos: self.parent.pos
on_press: root.centerize(*args)
text: "Out of the Grid"
Button:
on_press: self.parent.top = root.height
text: "Up"
""")
class Example(FloatLayout):
def __init__(self, **kwargs):
super(Example, self).__init__(**kwargs)
self.center_button.parent.bind(pos=self.binder)
self.centered = False
def binder(self, instance, value):
self.center_button.pos = instance.pos
def centerize(self, instance):
if self.centered:
self.center_button.parent.bind(pos=self.binder)
self.center_button.y = self.center_button.parent.y
self.centered = False
else:
self.center_button.parent.unbind(pos=self.binder)
self.center_button.center_y = self.height/2
self.centered = True
class ExampleApp(App):
def build(self):
return Example()
if __name__ == "__main__":
ExampleApp().run()

Categories