我想知道如何在Frame
内隐藏图像下的按钮而不会扭曲图像大小。我假设我需要使用网格,但我不知道如果没有它的宽高比变得疯狂,如何使图像适合。似乎无法使用grid()
在网格中创建隐藏按钮,然后使用pack()
将图像打包在顶部。有什么想法吗?
我试过了:
self.go_to_hydra = Button(self, text="Go to",
command=lambda: self.controller.show(Hydra_Level, self))
self.go_to_hydra.grid(row=20, column=20, rowspan=10, columnspan=10)
self.map_picture = PhotoImage(file=r"images/rsz_archipelago.gif")
self.image = Label(self, image=self.map_picture)
self.image.grid(row=0, column=0, columnspan=40, rowspan=40)
当我首先对按钮进行网格化时,它会显示在顶部并起作用。当我将它网格化时,它没有出现,这是有意义的,但当我点击它的位置时,不会触发任何事件。
答案 0 :(得分:1)
你不能像Tkinter一样隐藏彼此之间的元素。但是,您可以通过定义表示图像的不同“按钮”区域的矩形并确定是否自己单击了其中任何一个来获得类似的结果。在Tkinter术语中,我将图像设为Label
小部件并将<Button-1>
点击事件处理程序绑定到它。
这需要手动计算出图像中各个区域的坐标。幸运的是,通常可以通过将图像加载到图像编辑器中并记录要定义的每个区域的角的x和y值并将它们放入脚本中来轻松完成。对于下面的演示代码,我将测试图像分成以下红色显示的六个区域:
from collections import namedtuple
import Tkinter as tk
Rect = namedtuple('Rect', 'x0, y0, x1, y1')
class ImageMapper(object):
def __init__(self, image, img_rects):
self.width, self.height = image.width(), image.height()
self.img_rects = img_rects
def find_rect(self, x, y):
for i, r in enumerate(self.img_rects):
if (r.x0 <= x <= r.x1) and (r.y0 <= y <= r.y1):
return i
return None
class Demo(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.msg_text = tk.StringVar()
self.msg = tk.Message(self, textvariable=self.msg_text, width=100)
self.msg.grid(row=0, column=0)
self.picture = tk.PhotoImage(file='archipelago2.gif')
img_rects = [Rect(0, 26, 80, 78),
Rect(89, 26, 183, 78),
Rect(119, 120, 168, 132),
Rect(126, 74, 219, 125),
Rect(134, 135, 219, 164),
Rect(0, 148, 21, 164)]
self.imagemapper = ImageMapper(self.picture, img_rects)
# use Label widget to display image
self.image = tk.Label(self, image=self.picture, borderwidth=0)
self.image.bind('<Button-1>', self.image_click)
self.image.grid(row=1, column=0)
self.quitButton = tk.Button(self, text='Quit', command=self.quit)
self.quitButton.grid(row=2, column=0)
def image_click(self, event):
hit = self.imagemapper.find_rect(event.x, event.y)
self.msg_text.set('{} clicked'.format('nothing' if hit is None else
'rect[{}]'.format(hit)))
app = Demo()
app.master.title('Image Mapper')
app.mainloop()
以下是它运行的一些截图:
(您可以从here下载上面使用的archipelago2.gif
图片的副本。)