Reputation: 11
At the moment, I have a simple application that draws ellipses at the points of pressing, and saves a screenshot on the "Next" button. How to add this bundle of existing widgets to pagelayout so that when the button is clicked, a new page appears, on which, for example, there will be different content, and the "back" button returns to the previous page?
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import (Color, Ellipse, Rectangle, Line)
from kivy.uix.button import Button
from kivy.core.window import Window
from random import random
from kivy.uix.pagelayout import PageLayout
class PainterWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
Color(1., 0, 0, 0.49)
rad = 10
Ellipse(pos = (touch.x - rad/2, touch.y - rad/2), size= (rad, rad))
touch.ud['line'] = Line(points = (touch.x, touch.y), width = 10)
def on_touch_move(self, touch):
touch.ud['line'].points += (touch.x, touch.y)
class PaintApp(App):
def build(self):
# first page of PageLayout
pgl = PageLayout()
parent = Widget()
self.painter = PainterWidget()
parent.add_widget(self.painter)
Clock.schedule_once(self.set_background, 0)
# parent.add_widget(Button(text="Назад", on_press=self.save_canvas, size=(100, 50)))
parent.add_widget(Button(text="Clear", on_press=self.clear_canvas, size=(100, 50), pos = (100, 0)))
parent.add_widget(Button(text="Next", on_press=self.screen_canvas, size=(100, 50), pos=(200, 0)))
parent2 = Widget()
parent2.add_widget(Button(text="Clear", on_press=self.clear_canvas, size=(100, 50), pos=(100, 0)))
parent2.add_widget(Button(text="Next", on_press=self.screen_canvas, size=(100, 50), pos=(200, 0)))
# second page of PageLayout
pgl.add_widget(parent2)
return pgl
def clear_canvas(self, instance):
self.painter.canvas.clear()
def save_canvas(self, instance):
self.painter.size = (Window.size[0], Window.size[1])
self.painter.export_to_png('image.png')
def screen_canvas(self, instance):
Window.screenshot('screem.png')
print('This message has been sended for: 278 peoples')
def set_background(self, *args):
self.root_window.bind(size=self.do_resize)
with self.root_window.canvas.before:
self.bg = Rectangle(source='map.png', pos=(0, 0), size=(self.root_window.size))
def do_resize(self, *args):
self.bg.size = self.root_window.size
if __name__ == "__main__":
PaintApp().run()
Upvotes: 0
Views: 160
Reputation: 38992
The PageLayout
widget seems to be very fragile. I could only get it to work by using kv
. Here is a modified version of your code that does most of what you want:
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse, Line
from kivy.core.window import Window
kv = '''
PageLayout:
RelativeLayout:
id: page1
canvas.before:
Rectangle:
source: 'map.png'
size: self.size
PainterWidget:
id: painter
Button:
text: "Clear"
on_press: app.clear_canvas()
size_hint: (None, None)
size: (100, 50)
pos: (100, 0)
Button:
text: "Next"
on_press: app.screen_canvas()
size_hint: (None, None)
size: (100, 50)
pos: (200, 0)
RelativeLayout:
id: page2
canvas.before:
Color:
rgba: 0,1,0,1
Rectangle:
size: self.size
Button:
text: "Clear"
on_press: app.clear_canvas()
size_hint: (None, None)
size: (100, 50)
pos: (100, 0)
Button:
text: "Next"
on_press: app.screen_canvas()
size_hint: (None, None)
size: (100, 50)
pos: (200, 0)
'''
class PainterWidget(Widget):
def __init__(self, **kwargs):
self.line = None
super(PainterWidget, self).__init__(**kwargs)
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
touch.grab(self) # without this, PageLayout stops dispatching touches
with self.canvas:
Color(1., 0, 0, 0.49)
rad = 10
Ellipse(pos = (touch.x - rad/2, touch.y - rad/2), size= (rad, rad))
touch.ud['line'] = Line(points = (touch.x, touch.y), width = 10)
return super(PainterWidget, self).on_touch_down(touch)
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
if 'line' in touch.ud:
touch.ud['line'].points += (touch.x, touch.y)
return super(PainterWidget, self).on_touch_move(touch)
class PaintApp(App):
def build(self):
return Builder.load_string(kv)
def clear_canvas(self):
self.root.ids.painter.canvas.clear()
def save_canvas(self):
self.root.ids.painter.size = (Window.size[0], Window.size[1])
self.root.ids.painter.export_to_png('image.png')
def screen_canvas(self):
Window.screenshot('screem.png')
print('This message has been sended for: 278 peoples')
if __name__ == "__main__":
PaintApp().run()
In the above code, the Next
Button does not move to the next page. That is normally done with a swipe. If you actually want to use the Button, you can just set the page
property of PageLayout
to the index of the desired page (in your case, 0
or 1
).
Upvotes: 1