【问题标题】:Tkinter buttons getting hidden behind other framesTkinter 按钮隐藏在其他框架后面
【发布时间】:2021-11-22 00:37:39
【问题描述】:

我正在尝试为 dnd (picture) 创建一个带有可调节网格和可移动敌人/生物标记的战斗地图。想法是将其中一个标记从右侧拖到左侧的地图上。

窗口由 3 个框架组成。地图的框架,“新地图”按钮和滑块的框架。然后是标记的框架,这些标记是使用 button.grid() 平铺的按钮

我找到了一个拖放系统here,我用它来拖动令牌。但是,当我将它们带到地图上时,它们会在地图后面而您看不到它们(我知道它们会在后面,因为它们可以在两个框架之间部分可见)。有什么办法可以把他们带到前线吗?

import tkinter as tk

class DragManager():
    def add_dragable(self, widget):
        widget.bind("<ButtonPress-1>", self.on_start)
        widget.bind("<B1-Motion>", self.on_drag)
        widget.bind("<ButtonRelease-1>", self.on_drop)
        widget.configure(cursor="hand1")

    def on_start(self, event):
        # you could use this method to create a floating window
        # that represents what is being dragged.
        pass

    def on_drag(self, event):
        # you could use this method to move a floating window that
        # represents what you're dragging
        event.widget.place(x=event.x_root + event.x, y= event.y_root + event.y)

    #when button is dropped, create a new one where this one originally was
    def on_drop(self, event):
        # find the widget under the cursor
        x,y = event.widget.winfo_pointerxy()
        target = event.widget.winfo_containing(x,y)
        try:
            target.configure(image=event.widget.cget("image"))
        except:
            pass
        if x > window.winfo_screenwidth() - 200:
            del event.widget
            return
        if not event.widget.pure:
            return
        button = tk.Button(master=entity_select_frame, text = "dragable", borderwidth=1, compound="top")
        #avoiding garbage collection
        button.gridx = event.widget.gridx
        button.gridy = event.widget.gridy
        button.grid(row = event.widget.gridx, column = event.widget.gridy)
        button.grid()
        button.pure = True
        dnd.add_dragable(button)

window = tk.Tk()
window.geometry("1000x800")
map_frame = tk.Frame()
controls_frame = tk.Frame(width=200, borderwidth=1, relief=tk.RAISED)
tk.Label(master=controls_frame, text="controls here").pack()
entity_select_frame = tk.Frame(width=200, relief=tk.RAISED, borderwidth=1)

dnd = DragManager()
button = tk.Button(master=entity_select_frame, text = "dragable", borderwidth=1)
button.gridx = 0
button.gridy = 0
button.grid(row = 0, column = 0)
button.pure = True
dnd.add_dragable(button)


map_frame.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)
controls_frame.pack(fill=tk.BOTH)
entity_select_frame.pack(fill=tk.BOTH)
window.mainloop()

【问题讨论】:

标签: python tkinter


【解决方案1】:

我玩了一下,使用了this post 的东西。我没有将它构建为一个类,而是使用图片框架作为我的根框架并将控制框架放在其中。我不确定这将如何与您的“绘制网格”、“令牌”功能等最佳结合,但我希望它有所帮助。我没有找到一种方法来跨框架拖动小部件(尝试为按钮设置一个新的主控,在放下它后重新创建它等等)。从here获取我的代码中使用的图像。

from tkinter import Tk, Frame, Label, Button, Canvas, font
from tkinter import ttk
from PIL import Image, ImageTk

root = Tk()

""" ####################### Configuration parameters ###################### """
image_file_path = "Island_AngelaMaps-1024x768.jpg"
resize_img = False  # set to True if you want to resize the image > window size
resize_to = (600, 600)  # resolution to rescale image to


""" ####################### Drag and drop functionality ################### """


def make_draggable(widget):
    widget.bind("<Button-1>", on_drag_start)
    widget.bind("<B1-Motion>", on_drag_motion)


def on_drag_start(event):
    widget = event.widget
    widget._drag_start_x = event.x
    widget._drag_start_y = event.y


def on_drag_motion(event):
    widget = event.widget
    x = widget.winfo_x() - widget._drag_start_x + event.x
    y = widget.winfo_y() - widget._drag_start_y + event.y
    widget.place(x=x, y=y)


""" ################################# Layout ############################## """

# picture frame with picture as background
picture_frame = Frame(root)
picture_frame.pack(side="left", anchor="w", fill="both", expand=True)

# load the image
if resize_img:
    img = ImageTk.PhotoImage(Image.open(image_file_path).resize(resize_to, Image.ANTIALIAS))
else:
    img = ImageTk.PhotoImage(Image.open(image_file_path))

# create canvas, set canvas background to the image
canvas = Canvas(picture_frame, width=img.width(), height=img.height())
canvas.pack(side="left")
canvas.background = img  # Keep a reference in case this code is put in a function.
bg = canvas.create_image(0, 0, anchor="nw", image=img)

# subframe inside picture frame for controls
ctrl_subframe = Frame(picture_frame)
ctrl_subframe.pack(side="right", anchor="n")

# separator between picture and controls, inside picture frame
ttk.Separator(picture_frame, orient="vertical").pack(side="right", fill="y")

# underlined label 'Controls' in subframe
ctrl_header = Label(ctrl_subframe, text="Controls", font=("Arial", 10, "bold"))
f = font.Font(ctrl_header, ctrl_header.cget("font"))
f.configure(underline=True)
ctrl_header.configure(font=f)
ctrl_header.pack(side="top", pady=2)

# update window to get proper sizes from widgets
root.update()

# a draggable button, placed below ctrl_header
# (based on X of ctrl_subframe and height of ctrl_header, plus padding)
drag_button = Button(picture_frame, text="Drag me", bg="green", width=6)
drag_button.place(x=ctrl_subframe.winfo_x()+2, y=ctrl_header.winfo_height()+10)
make_draggable(drag_button)


""" ################################ Mainloop ############################# """

root.mainloop()

【讨论】:

    猜你喜欢
    • 2011-11-12
    • 2015-03-21
    • 2019-04-14
    • 2018-06-04
    • 1970-01-01
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    相关资源
    最近更新 更多