I designed this program
python code:
from random import random
from kivymd.app import MDApp as App
from kivymd.uix.widget import MDWidget as Widget
from kivy.graphics import Ellipse, Color, Line
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.button import MDIconButton
from kivy.lang import Builder
from kivy.properties import ObjectProperty
class Main(Screen):
draw = ObjectProperty(None)
class About(Screen):
pass
class Manager(ScreenManager):
mgr = ObjectProperty(None)
def cleaner(self):
self.mgr.draw.clean()
def color(self,color):
MyPaintWidget.color = color
class MyPaintWidget(Widget):
color = (0,0,0,1)
def clean(self):
self.canvas.clear()
def on_touch_down(self, touch):
# self.rect.pos = touch.pos
color = self.color
with self.canvas:
Color(*color)
d = 10
touch.ud['line'] = Line(points=(touch.x, touch.y),width = 5)
def on_touch_up(self,touch):
with self.canvas:
d = 10
Ellipse(pos=(touch.x - d / 2, touch.y - d / 2), size=(d, d))
def on_touch_move(self, touch):
# self.rect.pos = touch.pos
touch.ud['line'].points += [touch.x, touch.y]
#main_style = Builder.load_file("ms_paint.kv")
class MyPaintApp(App):
def build(self):
self.root = Builder.load_file("ms_paint.kv")
if __name__ == '__main__':
MyPaintApp().run()
kv file:
#:import get_color_from_hex kivy.utils.get_color_from_hex
Manager:
mgr: sc_mgr
Main:
id: sc_mgr
About:
<MyPaintWidget>:
on_touch_down: self.on_touch_down
on_touch_move: self.on_touch_move
<Main>:
name: "main"
draw: main_draw
BoxLayout:
orientation: "vertical"
MyPaintWidget:
id: main_draw
size_hint: 1, 0.9
GridLayout:
size_hint: 1, 0.1
cols: 7
padding: 10
#Button:
#text: "About"
#on_press:
#root.manager.current= "about"
#root.manager.transition.direction= "left"
MDIconButton:
icon: "eraser-variant"
on_press: root.manager.cleaner()
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: (0,0,0,1)
on_press: root.manager.color((0,0,0,1))
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: get_color_from_hex("#ff0000")
on_press: root.manager.color((255,0,0,1))
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: get_color_from_hex("#00ff00")
on_press: root.manager.color((0,255,0,1))
MDIconButton:
icon: "circle"
theme_icon_color: "Custom"
icon_color: get_color_from_hex("#0000ff")
on_press: root.manager.color((0,0,255,1))
<About>:
name: "about"
BoxLayout:
orientation: "vertical"
padding: 10
Label:
size_hint: 1, 0.9
text: "This is a free and open source paint app, made by a teacher of HamRuyesh community."
Button:
size_hint: 1, 0.9
text:"Back to Main"
on_press:
root.manager.current= "main"
root.manager.transition.direction= "right"
My problem is that I do not want to draw a line in the bottom bar, which is a grid layout, and I just want to be able to draw from that part. please guide me.
..........................................................................................................................................
You can use StencilView to limit the drawing area.
Thus You might change the MyPaintWidget(Widget) as
class MyPaintWidget(BoxLayout, StencilView):
Related
I'm making a game in kivy, it's a soccer juggling game. I want the game to be over whenever the soccer ball falls off the screen, also I want a restart button when the game is over so I can play again. I tried a lot of things but it doesn't seem to work. Any help is appreciated. Below is my code! Thank You!
main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.image import Image
from kivy.core.audio import SoundLoader
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.vector import Vector
class HomeScreen(Screen):
pass
def play_sound(self):
sound = SoundLoader.load('button press sound.wav.')
if sound:
sound.play()
sound = SoundLoader.load('Crowd sound effect.wav')
sound.loop = True
sound.play()
class GameScreen(Screen):
pass
def play_sound(self):
sound = SoundLoader.load('button press sound.wav.')
if sound:
sound.play()
class Ball(Image):
velocity = NumericProperty(0)
def on_touch_down(self, touch):
if Vector(self.center).distance(touch.pos) <= 33:
label = App.get_running_app().root.get_screen('game_screen').ids.score
label.text = str(int(label.text) + 1)
sound = SoundLoader.load('Soccer ball sound.wav')
sound.play()
self.source = "icons/ball.png"
self.velocity = 275
return super().on_touch_down(touch)
def on_touch_up(self, touch):
if Vector(self.center).distance(touch.pos) <= 33:
self.source = "icons/ball.png"
return super().on_touch_up(touch)
class MainApp(App):
GRAVITY = 300
def move_ball(self, time_passed):
ball = self.root.ids.game_screen.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
self.check_collision()
def check_collision(self):
ball = self.root.ids.game_screen.ids.ball
if ball.top < 96:
self.game_over()
def game_over(self):
print("game over")
def start_game(self):
Clock.schedule_interval(self.move_ball, 1/60.)
self.root.ids.game_screen.ids.score.text = "0"
def change_screen(self, screen_name):
self.root.current = screen_name
MainApp().run()
homescreen.kv
#:import utils kivy.utils
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .9
Image:
source: "icons/keepyup.png"
FloatLayout:
Button:
font_size: dp(20)
font_name: 'SackersGothicStd-Medium.otf'
text: "PLAY"
color: "gold"
pos_hint: { "center_x": .5, "center_y": .3}
size: 80, 55
size_hint: None, None
background_normal: ''
background_color: (57/255.0, 179/255.0, 242/255.0, .10)
on_press:
on_release:
root.play_sound()
root.manager.transition = FadeTransition()
app.change_screen("game_screen")
gamescreen.kv
#:import utils kivy.utils
<GameScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
Image:
source: "icons/sun.png"
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .2
Image:
source: "icons/clouds.png"
GridLayout:
rows: 1
pos_hint: {"bottom": 1, "left": 1}
size_hint: 1, .5
Image:
source: "icons/Field4.png"
allow_stretch: True
keep_ratio: False
pos: self.pos
Label:
id: score
size_hint: None, None
font_size: dp(25)
font_name: 'SackersGothicStd-Medium.otf'
text: "0"
color: "gold"
pos_hint: { "center_x": 0.1, "center_y": 0.9}
Button:
size_hint: None, None
font_size: dp(20)
font_name: 'SackersGothicStd-Medium.otf'
text: "Start Game"
color: "gold"
pos_hint: { "center_x": 0.5, "center_y": 0.3}
size: 150, 55
size_hint: None, None
background_normal: ''
background_color: (57/255.0, 179/255.0, 242/255.0, .10)
on_release:
self.disabled = True
self.opacity = 0
root.play_sound()
app.start_game()
Ball:
source: "icons/ball.png"
size_hint: None, None
size: 500, 500
pos_hint: {"center_x": 0.5}
id: ball
main.kv
#:include kv/homescreen.kv
#:include kv/gamescreen.kv
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
GameScreen:
name: "game_screen"
id: game_screen
Firstly, define a name for clock so you can stop it when game over:
self.control = Clock.schedule_interval(self.move_ball, 1/60.)
In game_over func, let's stop this clock:
self.control.cancel()
Now we need to create BoxLayout for our popup: ( game_over function )
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
bx = BoxLayout(orientation='vertical')
restart_but = Button(text='Restart')
restart_but.bind(on_release=self.restart_game)
bx.add_widget(Label(text='Score :'+self.root.ids.game_screen.ids.score.text))
bx.add_widget(restart_but)
self.popup = Popup(title='Game Over',content=bx,size_hint=(None, None), size=(400, 400))
self.popup.open()
Now as we define release command to restart_but, need to create new function:
def restart_game(self,*args):
self.popup.dismiss() #Close popup
#default settings here..
self.control = Clock.schedule_interval(self.move_ball, 1/60.) #Start Game
In restart_game function, you need to reset all settings like ball's position and score.
Also I suggest you to use KivyMD for sightly popups and buttons.
I have been trying off and on for two weeks to figure this out with no luck. This is the first time in my coding learning journey i've felt actually completely stuck. Any help is incredibly appreciated.
Right now my issue is changing screens outside of my .kv file. Right now I am trying to use:
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.current = "ScreenVideo1"
MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')
But that gives the error code:
'RootScreen' object has no attribute 'ScreenVideo1'
main.py
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import ObjectProperty
from kivy.uix.videoplayer import VideoPlayer
from kivy.uix.actionbar import ActionBar
from kivy.uix.button import Button
from kivy.core.window import Window
#remove after dev
Window.size = (300,500)
Window.clearcolor = (.976, .980, .996, 1)
screen_helper = r"""
RootScreen:
MDNavigationLayout:
ScreenManager:
id: screen_manager
ScreenHome:
id: screen_home
manager: screen_manager
name: "Home"
ScrollView:
pos_hint: {'bottom':1}
do_scroll_y: True
BoxLayout:
orientation: 'vertical'
padding: 15
spacing: 20
#size_hint: None, None
height: self.minimum_height
size_hint: (1, 2)
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
StrokeButton:
text: "Video Category 1"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release: screen_manager.current = "Video1"
ScreenAbout:
id: screen_about
manager: screen_manager
name: "About"
MDLabel:
text: "About"
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
ScreenHelp:
id: screen_help
manager: screen_manager
name: "Help"
MDLabel:
text: "Help"
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
ScreenVideo1:
id: screen_video1
manager: screen_manager
name: "Video1"
GridLayout:
pos_hint: {'top': 1}
cols:1
rows:5
ActionBar:
pos_hint: {'top': 1}
height:'100sp'
ActionView:
ActionPrevious:
with_previous: True
on_release: screen_manager.current = "Home"
StrokeButton:
text: " Video option 1"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release: root.onNextScreen(self, 'heart')
StrokeButton:
text: "Video option 2"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release:
StrokeButton:
text: "Video option 3"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release:
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation: 'vertical'
spacing: '8dp'
padding: '8dp'
MDLabel:
text: "blah blah blah"
font_style: 'Subtitle1'
size_hint_y: None
height: self.texture_size[1]
MDLabel:
text: "blah blah blah"
font_style: "Caption"
size_hint_y: None
height: self.texture_size[1]
ScrollView:
MDList:
OneLineIconListItem:
on_release:
screen_manager.current = "Home"
text: 'Home'
IconLeftWidget:
icon:"folder-home"
on_release:
screen_manager.current = "Home"
OneLineIconListItem:
on_release:
screen_manager.current = "Help"
text: 'Help'
IconLeftWidget:
icon:"help-circle-outline"
on_release:
screen_manager.current = "Help"
OneLineIconListItem:
on_release:
screen_manager.current = "About"
text: 'About'
IconLeftWidget:
icon: "doctor"
on_release:
screen_manager.current = "About"
<StrokeButton#Button>:
background_color:(0,0,0,0)
background_normal:''
back_color:(1,0,1,1)
border_radius: 18
color: self.back_color
bold: True
canvas.before:
Color:
rgba: self.back_color
Line:
rounded_rectangle: (self.pos[0],self.pos[1],self.size[0],self.size[1],self.border_radius)
width: 1.2
"""
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.current = "ScreenVideo1"
MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')
class ScreenHome(Screen):
pass
class ScreenAbout(Screen):
pass
class ScreenHelp(Screen):
pass
class ScreenVideo1(Screen):
def test_on_enter(self, vidname):
#self.add_widget(Button(text="Back"))
self.vid = VideoPlayer(source=vidname, state='play',
options={'allow_stretch':True,
'eos': 'loop'})
self.add_widget(self.vid)
def on_leave(self):
pass
def onBackBtn(self):
self.vid.state = 'stop'
self.remove_widget(self.vid)
MDApp.get_running_app().root.current = "ScreenVideo1"
class DemoApp(MDApp):
def build(self):
screen = Builder.load_string(screen_helper)
return screen
DemoApp().run()
It used to be very easy when I was building my app with Manager
class Manager(ScreenManager):
transition = NoTransition()
screen_one = ObjectProperty(None)
screen_two = ObjectProperty(None)
screen_home = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(Manager, self).__init__(*args, **kwargs)
# list to keep track of screens we were in
self.list_of_prev_screens = []
class ScreensApp(MDApp):
def build(self):
return Manager()
if __name__ == "__main__":
ScreensApp().run()
And then I would just change screens using manager. But now that I am using the navigation drawer I can no longer build my app with manager.
class ScreenOne(Screen):
def onNextScreen(self, btn, fileName):
self.manager.list_of_prev_screens.append(btn.parent.name)
self.manager.current = 'screen2'
self.manager.screen_two.test_on_enter(r'C:\file\location' + fileName + '.MOV')
Your code:
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.current = "ScreenVideo1"
MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')
is trying to treat the root widget of the App as a ScreenManager, but it isn't, it is a RootScreen. So, you need to access the ScreenManager, like this:
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.ids.screen_manager.current = "Video1"
MDApp.get_running_app().root.ids.screen_manager.current_screen.test_on_enter(r'C:\file\location' + fileName + '.MOV')
I am currently building a mobile app with kivy. In one of my screens I am trying to include an MDExpansionPanel, although I have tried with a lot of different codes, and searched on the web for solutions, either I get an error, or simply the Expansion Panel is not rendered in my screen. I am using ScreenManager since I have 5 screens, with the possibility of increasing such number.
The relevant Python code is the following:
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.app import MDApp
from kivymd.theming import ThemeManager
from kivymd.toast import toast
from kivymd.uix.picker import MDDatePicker, MDTimePicker
from kivymd.uix.expansionpanel import MDExpansionPanel
from kivymd.uix.boxlayout import MDBoxLayout
class LoginWindow(Screen):
pass
class CreateAccountWindow(Screen):
pass
class MainWindow(Screen):
pass
class TravelManagerWindow(Screen):
pass
class IngActivWindow(Screen):
panel_container = ObjectProperty(None)
def on_pre_enter(self, *args):
self.add_panels()
def show_timepicker(self):
picker = MDTimePicker()
picker.bind(time=self.got_time)
picker.open()
def got_time(self, picker_widget, time):
self.text = str(time.hour) + ":" + str(time.minute)
self.focus = False
# selectedTime= self.text
print(self.text)
self.ids.tiempoActiv.text = self.text
def add_panels(self):
for i in range(5):
IngActivWindow.ids.panel_container.add_widget(
MDExpansionPanel(
icon="actividades.png",
content=MyContent(),
panel_cls=MDExpansionPanelOneLine(
text="Text",
)
)
)
class MyContent(MDBoxLayout):
pass
class WindowManager(ScreenManager):
ScreenManager().add_widget(LoginWindow(name='login'))
ScreenManager().add_widget(CreateAccountWindow(name='create'))
ScreenManager().add_widget(MainWindow(name='main'))
ScreenManager().add_widget(IngActivWindow(name='ingActiv'))
ScreenManager().add_widget(TravelManagerWindow(name='travelManager'))
class powerApp1(MDApp):
def build(self):
self.theme_cls.primary_palette = "Teal"
return WindowManager()
if __name__ == "__main__":
powerApp1().run()
The relevant kv code is the following:
(I have an image on the background and an Action Bar before the MDBoxLayout where I am trying to add the Expansion Panel)
<WindowManager>:
LoginWindow:
CreateAccountWindow:
MainWindow:
IngActivWindow:
TravelManagerWindow:
<IngActivWindow>:
name: 'ingActiv'
panel_container: panel_container
FloatLayout:
cols:1
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'ingActiv_background.png'
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: '---------'
with_previous: False
ActionButton:
icon: 'homeIcon.png'
on_press:
root.manager.current = 'main'
root.manager.transition.direction = 'right'
ActionGroup:
text: 'Gastos de Viaje'
mode: 'spinner'
size_hint:(None,None)
size: root.width/5,root.height/12
ActionButton:
text: 'Solicitar'
on_release:
root.manager.current = 'solicitud'
root.manager.transition.direction = 'left'
ActionButton:
text: 'Comprobar'
on_release:
root.manager.current = 'comprobar'
root.manager.transition.direction = 'left'
ActionGroup:
text: 'Opciones'
mode: 'spinner'
size_hint:(None,None)
size: root.width/5,root.height/12
ActionButton:
text: 'Ingresar Actividad'
on_release:
root.manager.current = 'ingActiv'
root.manager.transition.direction = 'left'
ActionButton:
text: 'Enviar Reporte'
ActionButton:
text: 'Cerrar Sesion'
on_release:
root.manager.current = 'login'
root.manager.transition.direction = 'down'
MDBoxLayout:
cols:1
size_hint: 1,0.6
pos_hint: {"center_x": 0.5, "center_y": 0.5}
ScrollView:
GridLayout:
id: panel_container
cols: 1
pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyContent>:
size_hint: 1, None
height: self.minimum_height
orientation: 'horizontal'
Button:
size_hint: None, None
Thanks a lot in advance for your support,
Have a great day.
Problem
I have a screen (OrderScreen) that populates with buttons if there is data to be processed. I would like the user to click one of the buttons to be brought to another screen (MenuScreen) to process the data. While my intention is to populate the next screen with data from the button, I am currently just trying to get the ScreenManager to change to the next screen after a button press. I added a pass_data() method to the OrderButton and tried to trigger the screen manager there but self.manager.current and root.manager.current were throwing exceptions. Any help would be greatly appreciated.
recycleview_test.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.uix.recycleview import RecycleView
from kivy.uix.screenmanager import ScreenManager, Screen
from random import randint
class MenuScreen(Screen):
def quit(self):
App.get_running_app.stop()
Window.close()
class OrderScreen(Screen):
pass
class OrderButton(Button):
def __init__(self, **kwargs):
super(OrderButton, self).__init__(**kwargs)
def pass_data(self):
print("button pushed")
class OrderScroll(RecycleView):
def __init__(self, **kwargs):
super(OrderScroll, self).__init__(**kwargs)
self.data = [{'text': str(f"Make {randint(10, 25)} items from package #{randint(1,4)}")} for x in range(12)]
class WindowManager(ScreenManager):
pass
class RecycleApp(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
RecycleApp().run()
recycle.kv
#:import Factory kivy.factory.Factory
#: import ScreenManager kivy.uix.screenmanager.ScreenManager
#: import Screen kivy.uix.screenmanager.ScreenManager
#:import App kivy.app.App
<OrderScroll>:
viewclass: 'OrderButton'
manager: None
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
padding: 20
spacing: 10
<OrderButton>:
manager: None
font_size: 32
bold: True
on_release:
root.pass_data()
<WindowManager>:
id: screen_manager
OrderScreen:
id: order_screen
name: "OrderScreen"
manager: screen_manager
MenuScreen:
id: menu_screen
name: 'MenuScreen'
manager: screen_manager
<OrderScreen>:
BoxLayout:
orientation: "vertical"
Label:
text: "Data Buttons"
font_size: 64
size_hint_y: None
# pos_hint: {"x":0, "y":1}
height: 200
OrderScroll:
<MenuScreen>:
BoxLayout:
orientation: "vertical"
Label:
text: "Made it"
font_size: 64
FloatLayout:
Button:
text: 'Keep going'
font_size: 48
size_hint: .8,.5
pos_hint: {"center_x": .5, "center_y": .1}
FloatLayout:
Button:
text: 'Quit'
size_hint: .15,.3
pos_hint: {"center_x": .5, "center_y": .5}
on_release:
root.quit()
Try to create an object of screen manager:
class RecycleApp(App):
def build(self):
self.sm = WindowManager()
return self.sm
And then access it by:
App.get_running_app().sm.current = 'MenuScreen' # in Python
app.sm.current = 'MenuScreen' # in kv
I have a working Kivy code as given below. I am able to draw random shapes once I run it. Now, I want to enable drawing only after clicking the Hello button once. How should I modify my code?
Python code
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.graphics import Line
class Painter(Widget):
def on_touch_down(self, touch):
with self.canvas:
touch.ud["line"] = Line( points = (touch.x, touch.y))
def on_touch_move(self, touch):
touch.ud["line"].points += [touch.x, touch.y]
class MainScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
presentation = Builder.load_file("main3.kv")
class MainApp(App):
def build(self):
return presentation
if __name__=="__main__":
MainApp().run()
kv file:
#:kivy 1.0.9
ScreenManagement:
MainScreen:
<MainScreen>:
name:"main"
FloatLayout:
Painter
Button:
text: "Hello"
font_size: 50
color: 0,1,0,1
size_hint: 0.3,0.2
pos_hint: {"right":1, "top":1}
How about making a new screen for painting.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.graphics import Line
KV = '''
ScreenManagement:
MainScreen:
PaintScreen:
<MainScreen>:
name:"main"
FloatLayout:
Button:
text: "Go paint"
font_size: 50
color: 0,1,0,1
size_hint: 0.3,0.2
pos_hint: {"right":1, "top":1}
on_release:
root.manager.current = 'paint'
<PaintScreen#Screen>:
name: 'paint'
FloatLayout:
Button:
text: "Exit painting"
font_size: 40
color: 0,1,0,1
size_hint: 0.3,0.2
pos_hint: {"right":1, "top":1}
on_release:
root.manager.current = 'main'
Painter:
'''
class Painter(Widget):
def on_touch_down(self, touch):
with self.canvas:
touch.ud["line"] = Line( points = (touch.x, touch.y))
def on_touch_move(self, touch):
touch.ud["line"].points += [touch.x, touch.y]
class MainScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class MainApp(App):
def build(self):
return Builder.load_string(KV)
if __name__=="__main__":
MainApp().run()
You can use the a toggle button and link its state to the Painter:
...
Painter:
hello_active: hello_button.state == 'down'
ToggleButton:
id: hello_button
text: "Hello"
font_size: 50
color: 0,1,0,1
size_hint: 0.3,0.2
pos_hint: {"right":1, "top":1}
and in the python file...
class Painter(Widget):
hello_active = BooleanProperty(False)
def on_touch_down(self, touch):
if not self.hello_active:
return #nothing to see here ...
with self.canvas:
touch.ud["line"] = Line( points = (touch.x, touch.y))
def on_touch_move(self, touch):
if 'line' in touch.ud:
touch.ud["line"].points += [touch.x, touch.y]