Mino
Mino

Reputation: 3

Python How to clear window in tkinter

I need to clear window before I load a new map. But menu buttons have to stay. I was trying self.frame.destroy(), but it kill my menu buttons too. Basically I need to clear class Sokoban, but this class is not in class Window. Problem is in def map1(self): and def map2(self):

import tkinter
from tkinter import *

class Window(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master
        self.init_window()

    def init_window(self):
        self.master.title('Sokoban')
        self.pack(fill = BOTH, expand = 1)
        menu = Menu(self.master)
        self.master.config(menu=menu)

        file = Menu(menu)
        file.add_command(label='Mapa1', command = self.map1)
        menu.add_cascade(label='Mapy', menu=file)

        edit = Menu(menu)
        edit.add_command(label='Mapa2', command = self.map2)
        menu.add_cascade(label='Edit', menu=edit)

    def map1(self):
        self.frame.forget()
        Sokoban('map1.txt')

    def map2(self):
        self.frame.forget()
        Sokoban('map2.txt')


class Sokoban:

    def __init__(self, subor):
        t = open(subor, 'r')
        self.pole = [None] * 8
        self.box = []
        for a in range(8):
            self.pole[a] = list(t.readline().strip())
            for b in range(len(self.pole[a])):
                if self.pole[a][b] == '$':
                    self.player = Player(a,b)
                    self.pole[a][b] = '.'
                if self.pole[a][b] == '@':
                    self.box.append(Box(a,b))
                    self.pole[a][b] = '.'
        t.close()
        self.game = self.g = tkinter.Canvas(bg = 'white', width = 650, height = 240,
                                cursor = 'cross')
        self.g.pack()
        self.farba = [['gray'],['khaki'],['#FF4500'],['yellow'],['brown']]
        stena = '*'
        policko = '.'
        player = '$'
        box = '@'
        ciel = '+'
##        self.newButt = self.g.create_rectangle(511, 0, 650, 45, fill = 'red')
##        self.newButtText = self.g.create_text(580.5, 22.5, text = 'New Game',
##                                               font = 'arial 19 italic bold',
##                                              fill = 'yellow')
##        self.map1Butt = self.g.create_rectangle(511, 46, 650, 86, fill = 'red')
##        self.map1ButtText = self.g.create_text(580.5, 66, text = 'Map - 1',
##                                               font = 'arial 19 italic bold',
##                                               fill = 'yellow')
##        self.map2Butt = self.g.create_rectangle(511, 87, 650, 127, fill = 'red')
##        self.map2ButtText = self.g.create_text(580.5, 109, text = 'Map - 2',
##                                               font = 'arial 19 italic bold',
##                                               fill = 'yellow')
##        self.map3Butt = self.g.create_rectangle(511, 128, 650, 168, fill = 'red')
##        self.map3ButtText = self.g.create_text(580.5, 148, text = 'Map - 3',
##                                               font = 'arial 19 italic bold',
##                                               fill = 'yellow')
        self.kresli()
        self.g.bind_all('<Up>', self.up)
        self.g.bind_all('<Down>', self.down)
        self.g.bind_all('<Left>', self.left)
        self.g.bind_all('<Right>', self.right)
##        self.g.bind('<1>', self.Buttons)


    def up(self, e):
        self.move(-1, 0)

    def down(self, e):
        self.move(1, 0)

    def left(self, e):
        self.move(0, -1)

    def right(self, e):
        self.move(0, 1)

##    def newGame(self):
##        self.game.pack_forget()
##        Sokoban()

##    def map1(self):
##        self.game.pack_forget()
##        Sokoban('map1.txt')
##
##    def map2(self):
##        self.game.pack_forget()
##        Sokoban('map2.txt')

##    def Buttons(self, e):
##        if '<1>' and self.newButt:
##            self.newGame()

##        if '<1>' and self.map1Butt:
##            self.map1()
##
##        if '<1>' and self.map2Butt:
##            self.map2()

    def kresli(self):
        for a in range(8):
            for b in range(17):
                x,y = b*30, a*30
                f = self.farba['*.+'.index(self.pole[a][b])]
                self.g.create_rectangle(x,y,x+30,y+30,fill=f)
        self.player.kresli(self.g, self.farba[3])
        for box in self.box:
            box.kresli(self.g, self.farba[4])

    def setBox(self, r, s):
        for a in range(len(self.box)):
            if self.box[a].r==r and self.box[a].s==s:
                return a
        return -1

    def move(self, dr, ds):
        r = self.player.r + dr
        s = self.player.s + ds
        if r<0 or r>=8 or s<0 or s>=510 or self.pole[r][s] == '*':
            return
        c = self.setBox(r, s)
        if c >= 0:
            rr = r + dr
            ss = s + ds
            if rr < 0 or rr>=8 or ss<0 or ss>=510 or self.pole[rr][ss] == '*':
                return
            if self.setBox(rr, ss) >= 0:
                return
            self.box[c].move(dr, ds)
        self.player.move(dr, ds)

        for c in self.box:
            if self.pole[c.r][c.s] != '+':
                return

class Player:

    def __init__(self, r, s):
        self.r = r
        self.s = s

    def kresli(self, g, farba):
        self.g = g
        x,y = self.s*30, self.r*30
        self.plr = tkinter.PhotoImage(file='player.png')
        self.id1 = g.create_image(x+15, y+15, image = self.plr)

    def move(self, dr, ds):
        self.r = self.r + dr
        self.s = self.s + ds
        self.g.move(self.id1, ds*30, dr*30)

class Box:

    def __init__(self, r, s):
        self.r = r
        self.s = s

    def kresli(self, g, farba):
        self.g = g
        x,y = self.s*30, self.r*30
        self.bx = tkinter.PhotoImage(file='box.png')
        self.id2 = g.create_image(x+15, y+15, image = self.bx)

    def move(self, dr, ds):
        self.r = self.r + dr
        self.s = self.s + ds
        self.g.move(self.id2, ds*30, dr*30)


root = Tk()
root.geometry('510x240')
app = Window(root)
root.mainloop()
Sokoban()

Upvotes: 0

Views: 1443

Answers (1)

Lafexlos
Lafexlos

Reputation: 7735

That not-working wall of code is very hard to work with so I will try to answer your menu buttons have to stay part with an example code. Basically you create two frames, one holds widgets going to be cleared and second one holds other widgets plus first frame.

import tkinter as tk

root = tk.Tk()
root.geometry("300x300")

frame1 = tk.Frame(root)
frame2 = tk.Frame(frame1)
frame1.pack()
frame2.pack()
menubar = tk.Menu(frame1) 
menubar.add_command(label="Bring Back!", command=frame2.pack)
menubar.add_command(label="Quit!", command=root.destroy)

tk.Button(frame2, text="Forget only frame2", command=frame2.pack_forget).pack()
tk.Label(frame2, text="Label on frame2").pack()

root.config(menu=menubar)

root.mainloop()

Upvotes: 2

Related Questions