[英]Lift and raise a Canvas over a Canvas in tkinter
I'm creating a game, and I am using tkinter to build the GUI. 我正在创建一个游戏,并且正在使用tkinter来构建GUI。
In this game, I want the user to start with a window, filled by a Canvas, with an image as background, and some buttons in some sort of item windows. 在这个游戏中,我希望用户从一个以Canvas填充的窗口开始,以图像作为背景,并在某些项目窗口中添加一些按钮。 And this Canvas is the home Canvas of the game.
这个画布是游戏的主画布。
The problem is that I want the user to click on a Button to land on other Canvas, who will host other things like the map or others buttons for others actions. 问题是我希望用户单击按钮以登陆其他Canvas,后者将托管其他内容,例如地图或其他用于其他操作的按钮。 Actually, I would like to superimpose several canvas (as in the Z-index method), and put a canvas on the top of the list, when I want it (if I click on a button for example).
实际上,我想叠加几个画布(如Z-index方法一样),并在需要时将画布放在列表的顶部(例如,如果我单击按钮)。
I already searched and I had to change my mind several times, and now I really don't know how to do it. 我已经搜索过,不得不改变主意几次,现在我真的不知道该怎么做。
I find the following code here on Stack Overflow, but it is coded for Python 2 (I think), and I'm starting coding in Python 3, so I am not able to translate it to Python 3 and solve my problem. 我在Stack Overflow上找到了以下代码,但是它是为Python 2编码的(我认为),并且我开始在Python 3中进行编码,因此无法将其转换为Python 3并解决我的问题。
import Tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.frame = tk.Frame(self)
self.frame.pack(side="top", fill="both", expand=True)
self.label = tk.Label(self, text="Hello, world")
button1 = tk.Button(self, text="Click to hide label",
command=self.hide_label)
button2 = tk.Button(self, text="Click to show label",
command=self.show_label)
self.label.pack(in_=self.frame)
button1.pack(in_=self.frame)
button2.pack(in_=self.frame)
def show_label(self, event=None):
self.label.lift(self.frame)
def hide_label(self, event=None):
self.label.lower(self.frame)
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
My code using grid : 我的代码使用grid:
from tkinter import *
fenetre = Tk()
fenetre.title(my game)
# acceuil
# variable acceuil
largeur = 700
hauteur = 430
BG_acceuil = PhotoImage(file="BG_acceuil.gif")
acceuil = Canvas(fenetre, width=largeur, height=hauteur)
acceuil.create_image(0, 0, anchor=NW, image=BG_acceuil)
acceuil.grid(row=0)
acceuil.pack()
# fond
fond = PhotoImage(file="BG_acceuil.gif")
acceuil2 = Canvas(fenetre, width=largeur, height=hauteur)
acceuil2.create_image(0, 0, anchor=NW, image=fond)
acceuil2.pack()
# variable bt_jouer
x0 = 80
y0 = 230
class hide_me():
def hide_me(event, widget, pos):
widget.grid_forget()
def show_me(event, widget, pos):
widget.grid(row=pos)
# Boutton jouer
BT_jouer = Button(acceuil, text="Jouer", command=hide_me())
BT_jouer.configure(width=10, activebackground="#33B5E5", relief=GROOVE)
BT_jouer_window = acceuil.create_window(x0, y0, window=BT_jouer,)
BT_jouer.bind('<Button-1>', lambda event: hide_me(event, BT_jouer, 1))
BT_jouer.grid(row=1)
# Bouton règle
BT_regle = Button(acceuil2, text="Règles", command=fenetre.destroy)
BT_regle.configure(width=10, activebackground="#33B5E5", relief=FLAT, bd=0)
BT_regle_window = acceuil2.create_window(x0, y0 + 50, window=BT_regle)
# Boutton quitter
BT_quit = Button(acceuil, text="Quitter", command=fenetre.destroy)
BT_quit.configure(width=10, activebackground="#33B5E5", relief=FLAT)
BT_quit_window = acceuil.create_window(x0, y0 + 100, window=BT_quit)
fenetre.mainloop()
The answer is very easy: To convert to Python3, change Tkinter to tkinter, and it works! 答案很简单:要转换为Python3,请将Tkinter更改为tkinter,就可以了!
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.frame = tk.Frame(self)
self.frame.pack(side="top", fill="both", expand=True)
self.label = tk.Label(self, text="Hello, world")
button1 = tk.Button(self, text="Click to hide label",
command=self.hide_label)
button2 = tk.Button(self, text="Click to show label",
command=self.show_label)
self.label.pack(in_=self.frame)
button1.pack(in_=self.frame)
button2.pack(in_=self.frame)
def show_label(self, event=None):
self.label.lift(self.frame)
def hide_label(self, event=None):
self.label.lower(self.frame)
def main():
app = SampleApp()
app.mainloop()
return 0
if __name__ == '__main__':
main()
Note: You are not really hiding the label - it still occupies space on the canvas. 注意:您并没有真正隐藏标签-它仍然占用画布上的空间。 The following code , from this entry, really removes the item.
以下代码从该条目中真正删除了该项目。 It can then be recalled with a pack() call:
然后可以通过pack()调用来调用它:
from Tkinter import *
def hide_me(event):
event.widget.pack_forget()
root = Tk()
btn=Button(root, text="Click")
btn.bind('<Button-1>', hide_me)
btn.pack()
btn2=Button(root, text="Click too")
btn2.bind('<Button-1>', hide_me)
btn2.pack()
root.mainloop()
I did some testing, and made an equivalent program to yours... The only problem is that the unhidden widget is always packed at the end: 我做了一些测试,并制作了一个等效的程序……唯一的问题是,未隐藏的小部件总是放在最后:
from tkinter import *
def hide_me(event, widget):
widget.pack_forget()
def show_me(event, widget):
widget.pack()
root = Tk()
lbl = Label(root, text="Victim")
btn = Button(root, text="Hide the victim")
btn.bind('<Button-1>', lambda event: hide_me(event, lbl))
btn.pack()
btn2 = Button(root, text="Show the victim")
btn2.bind('<Button-1>', lambda event: show_me(event, lbl))
btn2.pack()
lbl.pack()
root.mainloop()
A better version uses the grid() packer. 更好的版本使用grid()打包程序。 Here you can actually restore the 'forgotten' widget to its original position.
在这里,您实际上可以将“已忘记”的小部件恢复到其原始位置。 Only slightly more complicated :)
只是稍微复杂一点:)
from tkinter import *
def hide_me(event, widget, pos):
widget.grid_forget()
def show_me(event, widget, pos):
widget.grid(row = pos)
root = Tk()
lbl = Label(root, text="Victim")
lbl.grid(row = 0)
btn = Button(root, text="Hide the victim")
btn.bind('<Button-1>', lambda event: hide_me(event, lbl, 0))
btn.grid(row = 1)
btn2 = Button(root, text="Show the victim")
btn2.bind('<Button-1>', lambda event: show_me(event, lbl, 0))
btn2.grid(row = 2)
root.mainloop()
EDIT: Another observation from the comments: Bryan Oakley commented that if you use .grid_remove()
instead of .grid_forget()
, then the coordinates will not be lost, and a simple .grid()
will restore the widget at its location. 编辑:评论中的另一个观察结果:布莱恩·奥克利(Bryan Oakley)评论说,如果使用
.grid_remove()
而不是.grid_forget()
,则坐标不会丢失,并且简单的.grid()
将在其位置恢复小部件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.