【发布时间】:2021-04-13 05:30:15
【问题描述】:
当我说动态网格时,我说的是根据窗口宽度调整列数(如引导程序)的网格,因此它必须相应地调整“卡片”,当我说可滚动时......好吧...更容易理解。
我尝试了两种方法:
- 创建一个动态网格,然后使其可滚动。
- 创建一个可滚动的网格,然后使其动态化。
我在这两个方面都失败了!我发现为了可滚动,网格不能在简单的框架中,它必须在 Canvas 中。而对于画布,我很难让它充满活力。
下面是我的动态网格代码
class DynaGrid(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, **kwargs)
self.columns = None
self.bind('<Configure>', self.re_grid)
def re_grid(self, event=None):
grid_width = self.winfo_width()
slaves = self.grid_slaves()
slaves_width = slaves[1].winfo_width()
cols = grid_width // slaves_width
if (cols == self.columns) | (cols == 0):
return
for i, slave in enumerate(reversed(slaves)):
slave.grid_forget()
slave.grid(row=i // cols, column=i % cols)
self.columns = cols
class CardFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, bd=1, relief=tk.RAISED, **kwargs)
tk.Label(self, text="Hello").pack()
def main():
root = tk.Tk()
frame = DynaGrid(root)
frame.pack(fill=tk.BOTH, expand=True)
CardFrame(frame).grid()
CardFrame(frame).grid()
CardFrame(frame).grid()
CardFrame(frame).grid()
CardFrame(frame).grid()
CardFrame(frame).grid()
CardFrame(frame).grid()
CardFrame(frame).grid()
root.mainloop()
if __name__ == '__main__':
main()
我不会浪费其他人的时间在这里发布我凌乱的画布代码,而是我有一个来自 https://blog.tecladocode.com/tkinter-scrollable-frames/ 我已经更改为使用我的“卡片”而不是标签。
import tkinter as tk
from tkinter import ttk
class ScrollableFrame(ttk.Frame):
def __init__(self, container, *args, **kwargs):
super().__init__(container, *args, **kwargs)
canvas = tk.Canvas(self)
scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
self.scrollable_frame = ttk.Frame(canvas)
self.scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
class TestFrame(tk.Frame):
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master, bd=5, relief=tk.RAISED, **kwargs)
tk.Label(self, text="name").pack(pady=10)
root = tk.Tk()
frame = ScrollableFrame(root)
for i in range(50):
TestFrame(frame.scrollable_frame).grid()
frame.pack()
root.mainloop()
要制作动态可滚动画布,这里的棘手部分是在画布内使用 re_grid 函数。我不知道如何像在 dynaGrid 代码中那样正确获取窗口宽度。
最后我想要这两个代码的混搭;一个类,它是某种带有横向滚动动态网格的框架。
【问题讨论】:
-
请不要问一个问题,然后发布其他人的代码,这些代码没有做你的代码正在做的事情。花点时间为您的问题创建一个合适的minimal reproducible example。另外,请发布语法正确的代码。您的第一个代码块有缩进错误。
-
您是真的想创建一个列宽相等的网格,还是只在一行内容不合适时将其包裹起来就足够了?
-
ident 已修复.. 抱歉.. 是的,我的网格将有等宽的列。在生产代码中,它将是 conf 类的属性
-
它不起作用,这样滚动与行不匹配......你说的画布周围的反转方式变成了“瓷砖”
-
我不知道您所说的“滚动与行不匹配”是什么意思。如果您有一个按照您想要的方式运行的框架,您只需将该框架添加到画布,以便您可以使用画布的滚动功能。
标签: python python-3.x tkinter grid-layout tkinter-canvas