我需要在加载新地图之前清除窗口。但是菜单按钮必须保留。我正在尝试self.frame.destroy(),但它也会杀死我的菜单按钮。基本上我需要清除类Sokoban,但这个类不在类Window中。问题出在 def map1(自我):和 def map2(自我):
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()
答案 0 :(得分:2)
代码无法使用的代码非常难以使用,因此我将尝试回答您的菜单按钮必须保留部分示例代码。 基本上你创建了两个框架,一个框架可以清除小部件,第二个框架可以容纳其他小部件和第一个框架。
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()