python-3.x - 避免 canvas create_window 与其他小部件重叠
问题描述
我正在 Windows 上使用 python 3.6 tkinter 制作类似扫雷的游戏。我使用了来自https://stackoverflow.com/a/47985165/8110056的代码。但是,create_window 对象在滚动时会与其他小部件重叠。我试图用框架包裹画布,但没有区别。
class Scrollable(tk.Frame):
"""
Make a frame scrollable with scrollbar on the right.
After adding or removing widgets to the scrollable frame,
call the update() method to refresh the scrollable area.
"""
def __init__(self, frame, **kwargs):
scrollbar = tk.Scrollbar(win,)
scrollbar.grid(row=0, column=1, sticky=tk.NS)#pack(side=tk.LEFT, fill=tk.Y, expand=True)
w = kwargs.get('width', MAP_WIDTH)
h = kwargs.get('height', MAP_HEIGHT)
self.canvas = tk.Canvas(frame, yscrollcommand=scrollbar.set, height=h-100, width=w-100, # produce
highlightthickness=0, borderwidth=5, background='#123456')
self.canvas.grid(row=2)
scrollbar.config(command=self.canvas.yview)
self.canvas.bind('<Configure>', self._fill_canvas)
super().__init__(frame, **kwargs)
self.windows_item = self.canvas.create_window(0,0, window=self, anchor=tk.NW,)
def _fill_canvas(self, event):
"Enlarge the windows item to the canvas width"
canvas_width = event.width
self.canvas.itemconfig(self.windows_item, width = canvas_width)
def update(self):
"Update the canvas and the scrollregion"
self.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))
win = tk.Tk()
MAP_WIDTH = 25*columns
MAP_HEIGHT = 25*rows
whole_frame = tk.Frame(win, relief=tk.RIDGE, borderwidth=10, )
whole_frame.grid(row=0, column=0)
top_frame = tk.Frame(whole_frame, width=MAP_WIDTH, padx=10)
top_frame.grid(sticky=tk.EW)
divider = tk.Frame(whole_frame, relief=tk.RAISED,
height=10, width=MAP_WIDTH, borderwidth=10)
divider.grid(row=1)
bottom_frame = Scrollable(whole_frame,)
realmap = [tk.Button(...) for i in range(rows*columns)]
for i in realmap:
i.grid(...)
bottom_frame.update()
win.update()
解决方案
可以通过将按钮的父级从 button_frame 更改为 self.canvas 来简单地解决此问题。
super().__init__(frame, **kwargs)
至
super().__init__(self.canvas, **kwargs)
推荐阅读
- javascript - 在联系人列表中添加个人资料后它不会在上面呈现...必须刷新页面,因为联系人数据被发送了两次
- snowflake-cloud-data-platform - 通过 Snowflake 中的主键/外键将数据插入到相互关联的多个表中
- python - 如何在 tesseract 中找到单词错误率?
- c# - 如何通过 asp.net core signalR 从 SQL Server 数据库中获取用户(学生)?
- swift - swift 5 中的 SQLite 实现?
- laravel - 记录用户 laravel 8 fortify 的最后登录时间戳和 ip
- python - 如果我创建一个调用像 numpy 这样的库的函数,而其他人使用它,他们需要安装 numpy 吗?
- python - 我不想在执行我的 exe 文件后显示控制台
- javascript - 如何将 pikaday 值与 laravel livewire 属性绑定
- python - netsh 跟踪开始/停止在 Python 子进程调用中不起作用