在 Tkinter 中改变框架
Changing Frames in Tkinter
我一直在教一个家庭朋友的女儿一些基本的编程。我们在 Python 中创建了一个不错的基本文字冒险游戏,它完全可以正常工作。但是,她真的很想以图形方式查看它,因此我尝试使用我对 Tkinter 的极其基础的知识来实现它。每一章都只是从前一章复制粘贴,按钮标签和链接、文本框内容和图像引用发生了变化。我已将每个单独的屏幕放入一个单独的函数中,通过单击前一个屏幕上的按钮调用该函数。但是,我的问题是,它们没有用新屏幕替换屏幕,而是彼此重叠。所以第二章的图像、按钮和文本只是放在第一章的下面。
我想不出一种方法来杀死以前的框架和小部件并用新的替换它们。我试过用几种方法杀死它们,但要么什么都不做,要么杀死整个程序。我也尝试过为每个功能中的按钮使用相同的名称,但因为它们是本地的,所以并没有真正的区别。
虽然我意识到它效率低下,但我想尽可能避免使用对象,因为向她解释会非常困难。
有什么办法可以通过调整我创建的结构来做到这一点,或者我只能通过使用复杂的 类 和对象来做到这一点吗?请记住,此代码永远不会被重用,因此无论它在后台有多混乱都没有关系。
from tkinter import *
root = Tk()
def intro():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side = BOTTOM)
photo = PhotoImage(file="hh.gif")
label = Label(root, image=photo)
label.pack(side = TOP)
t = Text(wrap=WORD, height = 10)
t.insert(INSERT, "This is the first screen")
t.insert(END, "")
t.pack()
# button 1 here should take us to the second screen
button1 = Button(bottomFrame, text="Option 1", fg="black", command=chapter2)
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side = LEFT)
button2.pack(side = LEFT)
button3.pack(side = LEFT)
root.mainloop()
def chapter2():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side = BOTTOM)
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(root, image=photo1)
label1.pack(side = TOP)
t1 = Text(wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.insert(END, "")
t1.pack()
button4 = Button(bottomFrame, text="this", fg="black")
button5 = Button(bottomFrame, text="that", fg="black")
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side = LEFT)
button5.pack(side = LEFT)
button6.pack(side = LEFT)
root.mainloop()
intro()
您的代码中发生的情况是,您正在创建新的文本字段和标签,而没有删除旧的。
要删除旧的 text/label 小部件,请使用 pack_forget()
,在您的情况下,t.pack_forget()
、label.pack_forget()
、button1.pack_forget()
、button2.pack_forget()
, 和 button3.pack_forget()
。 pack_forget()
所做的是从 window 中移动一个小部件,就像 pack()
的相反操作。因此,要将其添加到您的代码中,只需更改第 24 行:
button1 = Button(bottomFrame, text="Option 1", fg="black", command=chapter2
到
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (t.pack_forget(), label.pack_forget(), button1.pack_forget(), button2.pack_forget(), button3.pack_forget(), chapter2()))
(注意 在第二章中,您将使用 t1.pack_forget()
、label1.pack_forget()
、button4/5/6.pack_forget()
和 not t/label/button1/2/3.pack_forget()
)
您还必须在您的标签上保留对您照片的引用,您可以通过在 label = Label(topFrame, image=photo)
和 [=27] 之间添加 label.image = photo
来实现=] 另外,请参阅 this 页。
Entier 编辑代码:
from tkinter import *
root = Tk()
def intro():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
photo = PhotoImage(file="hh.gif")
label = Label(root, image=photo)
label.image = photo # keep a reference!
label.pack(side=TOP)
t = Text(wrap=WORD, height=10)
t.insert(INSERT, "This is the first screen")
t.insert(END, "")
t.pack()
# button 1 here should take us to the second screen
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (t.pack_forget(), label.pack_forget(), button1.pack_forget(), button2.pack_forget(), button3.pack_forget(), chapter2()))
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
def chapter2():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(root, image=photo1)
label.image = photo # keep a reference!
label1.pack(side=TOP)
t1 = Text(wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.insert(END, "")
t1.pack()
button4 = Button(bottomFrame, text="this", fg="black")
button5 = Button(bottomFrame, text="that", fg="black")
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side=LEFT)
button5.pack(side=LEFT)
button6.pack(side=LEFT)
intro()
root.mainloop()
希望这有帮助,如果没有,请发表评论,我会尝试找到其他解决方案:)
此外,如果您想知道 lambda 是什么(已编辑代码的一部分),只需 google "python lambda".
为了以 mocqoro 的回答为基础,我建议您将每一章都放在一个框架中。这样,当你想移动到下一章时,你可以只 pack_forget
或 destroy
(pack_forget
是很好的,如果你想稍后重新打包一个小部件,destroy
完全删除小部件)章节的框架而不是每个单独的小部件:
from tkinter import *
def intro():
chapterFrame = Frame(root)
chapterFrame.pack()
topFrame = Frame(chapterFrame) # top and bottom frames are children of chapterFrame
topFrame.pack()
photo = PhotoImage(file="hh.gif")
label = Label(topFrame, image=photo)
label.image = photo
label.pack(side=TOP)
t = Text(topFrame, wrap=WORD, height=10)
t.insert(INSERT, "This is the first screen")
t.pack()
bottomFrame = Frame(chapterFrame)
bottomFrame.pack(side=BOTTOM)
# button 1 here should take us to the second screen
# button1 deletes the entire chapter and calls chapter2
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (chapterFrame.destroy(), chapter2()))
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
def chapter2():
chapterFrame = Frame(root)
chapterFrame.pack()
topFrame = Frame(chapterFrame)
topFrame.pack()
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(topFrame, image=photo1)
label1.image = photo1
label1.pack(side = TOP)
t1 = Text(topFrame, wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.pack()
bottomFrame = Frame(chapterFrame)
bottomFrame.pack(side=BOTTOM)
button4 = Button(bottomFrame, text="this", fg="black")
# button5 loops back to intro
button5 = Button(bottomFrame, text="that", fg="black", command=lambda: (chapterFrame.destroy(), intro()))
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side=LEFT)
button5.pack(side=LEFT)
button6.pack(side=LEFT)
root = Tk()
intro()
root.mainloop()
我一直在教一个家庭朋友的女儿一些基本的编程。我们在 Python 中创建了一个不错的基本文字冒险游戏,它完全可以正常工作。但是,她真的很想以图形方式查看它,因此我尝试使用我对 Tkinter 的极其基础的知识来实现它。每一章都只是从前一章复制粘贴,按钮标签和链接、文本框内容和图像引用发生了变化。我已将每个单独的屏幕放入一个单独的函数中,通过单击前一个屏幕上的按钮调用该函数。但是,我的问题是,它们没有用新屏幕替换屏幕,而是彼此重叠。所以第二章的图像、按钮和文本只是放在第一章的下面。
我想不出一种方法来杀死以前的框架和小部件并用新的替换它们。我试过用几种方法杀死它们,但要么什么都不做,要么杀死整个程序。我也尝试过为每个功能中的按钮使用相同的名称,但因为它们是本地的,所以并没有真正的区别。
虽然我意识到它效率低下,但我想尽可能避免使用对象,因为向她解释会非常困难。
有什么办法可以通过调整我创建的结构来做到这一点,或者我只能通过使用复杂的 类 和对象来做到这一点吗?请记住,此代码永远不会被重用,因此无论它在后台有多混乱都没有关系。
from tkinter import *
root = Tk()
def intro():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side = BOTTOM)
photo = PhotoImage(file="hh.gif")
label = Label(root, image=photo)
label.pack(side = TOP)
t = Text(wrap=WORD, height = 10)
t.insert(INSERT, "This is the first screen")
t.insert(END, "")
t.pack()
# button 1 here should take us to the second screen
button1 = Button(bottomFrame, text="Option 1", fg="black", command=chapter2)
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side = LEFT)
button2.pack(side = LEFT)
button3.pack(side = LEFT)
root.mainloop()
def chapter2():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side = BOTTOM)
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(root, image=photo1)
label1.pack(side = TOP)
t1 = Text(wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.insert(END, "")
t1.pack()
button4 = Button(bottomFrame, text="this", fg="black")
button5 = Button(bottomFrame, text="that", fg="black")
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side = LEFT)
button5.pack(side = LEFT)
button6.pack(side = LEFT)
root.mainloop()
intro()
您的代码中发生的情况是,您正在创建新的文本字段和标签,而没有删除旧的。
要删除旧的 text/label 小部件,请使用 pack_forget()
,在您的情况下,t.pack_forget()
、label.pack_forget()
、button1.pack_forget()
、button2.pack_forget()
, 和 button3.pack_forget()
。 pack_forget()
所做的是从 window 中移动一个小部件,就像 pack()
的相反操作。因此,要将其添加到您的代码中,只需更改第 24 行:
button1 = Button(bottomFrame, text="Option 1", fg="black", command=chapter2
到
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (t.pack_forget(), label.pack_forget(), button1.pack_forget(), button2.pack_forget(), button3.pack_forget(), chapter2()))
(注意 在第二章中,您将使用 t1.pack_forget()
、label1.pack_forget()
、button4/5/6.pack_forget()
和 not t/label/button1/2/3.pack_forget()
)
您还必须在您的标签上保留对您照片的引用,您可以通过在 label = Label(topFrame, image=photo)
和 [=27] 之间添加 label.image = photo
来实现=] 另外,请参阅 this 页。
Entier 编辑代码:
from tkinter import *
root = Tk()
def intro():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
photo = PhotoImage(file="hh.gif")
label = Label(root, image=photo)
label.image = photo # keep a reference!
label.pack(side=TOP)
t = Text(wrap=WORD, height=10)
t.insert(INSERT, "This is the first screen")
t.insert(END, "")
t.pack()
# button 1 here should take us to the second screen
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (t.pack_forget(), label.pack_forget(), button1.pack_forget(), button2.pack_forget(), button3.pack_forget(), chapter2()))
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
def chapter2():
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(root, image=photo1)
label.image = photo # keep a reference!
label1.pack(side=TOP)
t1 = Text(wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.insert(END, "")
t1.pack()
button4 = Button(bottomFrame, text="this", fg="black")
button5 = Button(bottomFrame, text="that", fg="black")
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side=LEFT)
button5.pack(side=LEFT)
button6.pack(side=LEFT)
intro()
root.mainloop()
希望这有帮助,如果没有,请发表评论,我会尝试找到其他解决方案:)
此外,如果您想知道 lambda 是什么(已编辑代码的一部分),只需 google "python lambda".
为了以 mocqoro 的回答为基础,我建议您将每一章都放在一个框架中。这样,当你想移动到下一章时,你可以只 pack_forget
或 destroy
(pack_forget
是很好的,如果你想稍后重新打包一个小部件,destroy
完全删除小部件)章节的框架而不是每个单独的小部件:
from tkinter import *
def intro():
chapterFrame = Frame(root)
chapterFrame.pack()
topFrame = Frame(chapterFrame) # top and bottom frames are children of chapterFrame
topFrame.pack()
photo = PhotoImage(file="hh.gif")
label = Label(topFrame, image=photo)
label.image = photo
label.pack(side=TOP)
t = Text(topFrame, wrap=WORD, height=10)
t.insert(INSERT, "This is the first screen")
t.pack()
bottomFrame = Frame(chapterFrame)
bottomFrame.pack(side=BOTTOM)
# button 1 here should take us to the second screen
# button1 deletes the entire chapter and calls chapter2
button1 = Button(bottomFrame, text="Option 1", fg="black", command=lambda: (chapterFrame.destroy(), chapter2()))
button2 = Button(bottomFrame, text="Option 2", fg="black")
button3 = Button(bottomFrame, text="Option 3", fg="black")
button1.pack(side=LEFT)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
def chapter2():
chapterFrame = Frame(root)
chapterFrame.pack()
topFrame = Frame(chapterFrame)
topFrame.pack()
photo1 = PhotoImage(file="hh2.gif")
label1 = Label(topFrame, image=photo1)
label1.image = photo1
label1.pack(side = TOP)
t1 = Text(topFrame, wrap=WORD)
t1.insert(INSERT, "This is the second screen")
t1.pack()
bottomFrame = Frame(chapterFrame)
bottomFrame.pack(side=BOTTOM)
button4 = Button(bottomFrame, text="this", fg="black")
# button5 loops back to intro
button5 = Button(bottomFrame, text="that", fg="black", command=lambda: (chapterFrame.destroy(), intro()))
button6 = Button(bottomFrame, text="the other", fg="black")
button4.pack(side=LEFT)
button5.pack(side=LEFT)
button6.pack(side=LEFT)
root = Tk()
intro()
root.mainloop()