how to implement pagelayout?

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

Answers (1)

John Anderson
John Anderson

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

Related Questions