如何在kivy中清除屏幕

How to clear the screen in kivy

我正在制作一个简单的应用程序,它会显示一些食谱,您可以进入一个单独的 'recipe screen',其中会显示 image/ingredients 和制作食谱的说明。但是,我现在正在尝试制作一个按钮,让您 returns 进入食谱列表。该按钮有效,但我要返回的食谱屏幕和食谱列表似乎重叠,因此我需要弄清楚如何在移动到食谱列表屏幕之前清除食谱屏幕。但是,由于某些原因,clear_canvas() 或 clear_screen() 函数不起作用。我应该怎么做才能清除 kivy 屏幕?

这是重叠屏幕的图像:

Python代码:

import kivy
from kivy.app import App 
from kivy.uix.widget import Widget 
from kivy.lang import Builder 
from kivy.core.window import Window 
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.app import MDApp
from kivymd.uix.list import OneLineListItem, MDList, TwoLineListItem, ThreeLineListItem
from kivy.uix.image import Image 
from kivymd.uix.list import ThreeLineIconListItem, IconLeftWidget
from kivymd.uix.label import MDLabel
from kivy.uix.button import Button
from kivymd.icon_definitions import md_icons
from kivy.properties import ObjectProperty
from functools import partial
from kivy.uix.scrollview import ScrollView
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.config import Config
import time
import os
import shutil

global results 
results = [['Kiwi fruit smoothie', 4, 5, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/kiwi-smoothie-3086931.jpg', ['3 peeled kiwi fruit', '1 mango , peeled, stoned and chopped', '500ml pineapple juice', '1 banana , sliced'], 'Put all of the ingredients in a blender and blitz until smooth then pour into 2 tall glasses.'], ['Kiwi slime pies', 7, 55, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/kiwi-slime-pies-189a218.jpg', ['320g shop-bought ready-rolled shortcrust pastry', '4 egg yolks , plus 1 egg white (freeze the remaining whites to make meringues another day)', '400ml milk', '35g golden caster sugar', '1 heaped tbsp plain flour', '5 cubes green jelly', '2-3 green and golden kiwi fruit , peeled and sliced'], 'Heat the oven to 190C/170C fan/gas 5. Divide the pastry into eight equal pieces. Roll each out until large enough to line deep 7-8cm fluted tartlet tins or eight holes of a large muffin tin. Line the tins with the pastry, leaving a little sticking up above the rims, then line with paper cases and baking beans. Put the tins on a baking tray and bake for 10 mins, then remove the paper and beans, brush with the egg white and bake for 5-10 mins more until crisp and golden. Leave to cool for 5 mins, then remove from the tins and leave to cool completely.\nPut the milk in a pan and bring almost to the boil, then remove from the heat. Put the egg yolks, sugar and flour in a bowl and whisk with an electric whisk until pale and fluffy – it should leave a trail that stays on the surface momentarily when the whisk is lifted. Pour a third of the hot milk into the bowl, slowly whisking all the time, until it has all been mixed in. Whisk in the remaining milk.\nReturn the mixture to the pan, scraping it out using a rubber spatula. Bring slowly to the boil, stirring, until the custard is thick, smooth and glossy. At first, it will look a bit lumpy, but keep stirring and it will become smooth. Reduce the heat and simmer for 2 mins, stirring. Stir in the jelly until the cubes have dissolved. Leave the mixture to cool until just warm, then divide it between the baked tart cases. Top each with a slice of kiwi and leave to cool completely.'], ['Fruit salad', 7, 15, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/fruit-salad-9e9687f.jpg', ['2 kiwi', '1 mango', '150g pineapple', '100g grapes', '400g mixed berries , we used strawberries, raspberries and blackberries', '1 large orange', '2 tsp honey (optional)'], 'Prepare the fruit with a small serrated knife. Cut the top and bottom off the kiwi, stand it up on one of its flat surfaces and cut away the skin, keeping the knife as close to the skin as possible. Slice in half, following the core through the centre, then cut each half into slices. Put in a bowl and repeat with the other kiwi.\nCarefully cut the skin off the mango and slice off each cheek, running your knife as close to the stone as you can. Cut each piece into slices. Remove any remaining fruit from the stone in long thin slices. Add the mango to the kiwi.\nTop and tail the pineapple, then in a similar way to the kiwi, cut away the skin. Use your knife to go around the pineapple, taking out the divets or eyes, two to three at a time, you’ll be left with a spiral pattern weaving around the outside of the fruit. Take of a circular slice, roughly 150g, quarter, remove the core then cut into chunks. Add to the bowl.\nHalve the grapes and add to the rest of the fruit along with the berries, you may want to slice or halve strawberries if they’re large. Remove the peel from the orange using the same method as the kiwi and pineapple. Holding the orange over the bowl of fruit, remove the orange segments by carefully cutting between the membrane and the fruit. The pieces should fall out into the bowl along with any juice. Squeeze the membrane over the fruit to extract the juice, add a drizzle of honey, if you like. Mix everything together and leave in the fridge to macerate for 30 mins, if you have time.'], ['Rainbow fruit lollies', 6, 20, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/rainbow-fruit-lollies-40bcdbb.jpg', ['100g mango , peeled, stoned and chopped', '2 bananas', '400g yogurt', '2 kiwi fruit , peeled and roughly chopped', '100g frozen raspberries', '100g frozen blackberries'], 'Blitz the mango with ½ banana and 100g yogurt in a blender until smooth. Divide between six ice lolly moulds and insert a stick into each. Hold each stick upright in the mould, and secure on both sides with tape. Freeze for 1 hr until set.\nRepeat with another ½ banana, 100g more yogurt and the kiwi fruit, and pour that over the banana layer. Freeze for another 1 hr until set. Repeat with the raspberries, then the blackberries, freezing each layer before topping with the next. Cover and freeze the lollies overnight. Run under warm water to remove from the moulds. Will keep in the freezer for up to two months.'], ['Kiwiriqui', 7, 5, 'https://images.immediate.co.uk/production/volatile/sites/30/2021/03/kiwiriqui-99208b7.jpg', ['½ kiwi, plus a slice to garnish', '20ml kiwi liqueur', '10ml agave syrup', '20ml lime juice', '30ml QuiQuiRiqui Espadin mezcal', '30ml apple juice', 'ice'], 'Add the kiwi half, kiwi liqueur, agave syrup and lime juice to the bottom of a cocktail shaker and muddle together. Add the rest of the ingredients and shake together.\nStrain into a rocks glass filled with fresh ice and garnish with a slice of kiwi.'], ['Easy vegan tacos', 13, 40, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/chargrilled-tacos-3060d1e.jpg', ['175g pack baby corn', '1 large red onion , sliced (190g)', '1 red pepper , deseeded and roughly chopped', '½ tsp cumin seeds', '2 tsp olive oil', '1large ripe kiwi , halved lengthways (110g)', '1large tomato , halved (115g)', '100g wholemeal flour , plus extra for rolling', '1 large garlic clove', '15g fresh coriander , chopped', '1 tsp vegan bouillon powder', '½ tsp smoked paprika', '85g red cabbage , finely shredded'], 'Heat oven to 220C/200C fan/gas 7. Pile the corn, red onion and pepper into a large shallow roasting tin and toss with the cumin seeds and oil. Add the kiwi and tomato on one side of the tin and roast for 20 mins.\nMeanwhile, mix 60ml water into the flour with the blade of a knife to make a dough. Knead briefly until smooth, then cut equally into four and roll out each piece on a lightly floured surface into a 16cm round tortilla. Cover with a tea towel to stop them drying out.\nRemove the cooked tomato and kiwi from the tin and return the veg to the oven for 10 mins. Remove the skin from the kiwi and scoop the flesh into a bowl with the tomato, garlic, half the coriander, bouillon and paprika. Use a hand blender to blitz to a smooth salsa.\nHeat a large non-stick frying pan, without oil, and cook the tortillas one at a time for a minute on one side and about 10 seconds on the other, until you see them puff up a little. Spread a tortilla with some salsa, top with cabbage and roasted veg, then scatter with the remaining coriander. Add a spoonful more salsa and eat with your hands.'], ['Watermelon lollies', 2, 15, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/gfmelons_lollies-378a234.jpg', ['1 small watermelon', '3 kiwis'], 'Halve 1 small watermelon and scoop the flesh out of one half into a bowl (you need about 375-400g). Pick out any black seeds. Purée the flesh using a hand blender or in a liquidiser. Fill ice lolly moulds three-quarters full with the purée, push the sticks in if you are using them, and freeze for at least 3 hrs, or overnight. Tip any remaining purée into an ice cube tray and freeze it.\nPeel 3 kiwis and cut the green flesh away from the white core, discarding the core. Purée the flesh. Add a layer of about 4-5mm to the top of each lolly and refreeze for 1 hr. Add some green food colouring to the rest of the purée to darken it to the same colour as the watermelon rind. Pour a very thin layer onto the top of each lolly and freeze until you want to eat them.'], ['Super-easy fruit ice cream', 8, 20, 'https://images.immediate.co.uk/production/volatile/sites/30/2020/08/super-easy-fruit-ice-cream-b288af9.jpg', ['200g strawberries (as red as you can get), hulled', '1 large mango , deseeded and peeled', '¼ lemon , juiced', '3 very ripe bananas , peeled', '200g condensed milk', '600ml double cream', '4 kiwi fruit , peeled', 'sprinkles or finely chopped strawberries and mango, to serve'], 'Mash or purée the strawberries and mango in two separate bowls. In another bowl, add the lemon juice and the banana and mash.\nBeat the condensed milk and cream in a large bowl with an electric whisk until thick and quite stiff, a bit like clotted cream. Divide the mixture between the three bowls. Fold a fruit purée into each. Transfer each one into a freezer container and freeze until solid.\nPurée the kiwi and sieve out any seeds if you like. Serve a scoop of each ice cream in bowls or sundae dishes and top with the kiwi sauce, sprinkles, or the chopped fruit.']]
global md_index_matrix
md_index_matrix = {}

def change_screens(self, result):
    global selected_result 
    selected_result = results[md_index_matrix[str(result)]]
    global image_index
    image_index = md_index_matrix[str(result)]
    print('IMAGE INDEX: ', image_index)
    wm.current = 'second'


def go_back(self):
    self.clear_canvas()  # what should I replace this part with????
    wm.current='first'


class ResultsWindow(Screen):
    def on_enter(self): 
        list_view = MDList() # creating list view
        scroll = ScrollView() # scrollview 
        for x, result in enumerate(results):
            items = ThreeLineListItem(text=f"{result[0]}",
                                        secondary_text=f'number of ingredients: {result[1]}',
                                        tertiary_text=f'time taken to cook: {result[2]} minutes', #this part is for showing
                                        bg_color=(60/255, 188/255, 66/255, 1),                    #all of the recipes
                                        on_press=partial(change_screens, str(result)))
            md_index_matrix[str(items)] = x
            list_view.add_widget(items)
        scroll.add_widget(list_view)
        self.add_widget(scroll)


class RecipeWindow(Screen):
    def on_enter(self):
        self.image_index = f'food_images/{image_index}.png'
        scroll = ScrollView(size_hint=(None, None), size=(Window.width, Window.height), do_scroll_y=True)
        floatL = FloatLayout(size_hint=(None, None), size=(scroll.width, scroll.height*2))
        
        floatL.add_widget(Image(source=(f'food_images/{image_index}.png'), pos_hint={'x':0.2, 'y':0.45}, size_hint_x=0.6, size_hint_y=0.6))
        floatL.add_widget(Label(text=selected_result[0], pos_hint={'x':0, 'y':0.46}, font_size=32, color=(0, 0, 0, 1)))

        return_button = Button(text='Return', pos_hint={'x':0.1, 'y':0.46}, size_hint=(None, None), size=(100, 100))
        return_button.bind(on_press=lambda x:go_back(self))
        floatL.add_widget(return_button)


        ingredients=selected_result[4]
        floatL.add_widget(Label(text=f'Ingredients', pos_hint={'x':0, 'y':0.03}, font_size=30, color=(0, 0, 0, 1)))
        for x in range(len(ingredients)):
            print(ingredients[x])
            floatL.add_widget(Label(text=f'{ingredients[x]}', pos_hint={'x':0, 'y':0-(x*0.03)}, font_size=15, color=(0, 0, 0, 1)))


        scroll.add_widget(floatL)   
        self.add_widget(scroll)
        

class WindowManager(ScreenManager):
    pass

Builder.load_file('RockettApp.kv')

class TheApp(MDApp):
    def build(self):
        global wm
        self.title = 'App'

        wm = WindowManager()
        return wm

if __name__ == '__main__':
    TheApp().run()

kivy代码:

<WindowManager>:
    ResultsWindow:
    RecipeWindow:



<ResultsWindow>
    name: 'first'

    canvas.before:
        Color:
            rgba: 60/255, 188/255, 66/255, 1
        Rectangle:
            pos: self.pos
            size: self.size


<RecipeWindow>
    name: 'second'

    canvas.before:
        Color:
            rgba: 60/255, 188/255, 66/255, 1
        Rectangle:
            pos: self.pos
            size: self.size
    
    

            

由于您使用 on_enter() 方法将内容添加到 RecipeWindow,只需添加一个 on_leave() 方法来清除它:

class RecipeWindow(Screen):
    def on_leave(self, *args):
        self.clear_widgets()

那么你的go_back()方法可以是:

def go_back(self):
    # self.clear_canvas()  # what should I replace this part with????
    wm.current = 'first'