python - 处理 tkinter 框架中的视觉溢出?
问题描述
我正在编写一个添加滚动框架的类。它检测框架的内容何时超过其高度,然后配置滚动条。问题是当我向下滚动时,框架中的项目会滚动到框架顶部之外并出现在其上方。
我已经使用普通标签对其进行了测试,并且效果很好,但是我使用的是具有一些嵌套框架的类对象,并且子对象显示在滚动框架上方。
这是给我带来问题的代码的要点(请注意,布局与整个项目不匹配。我将此作为ScrollFrame()
课程的参考。)
只需运行它,按下按钮,然后向下滚动就会告诉你它有什么问题。
import tkinter as tk
import tkinter.simpledialog as sd
class ScrollFrame(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
### setting up the objects used ###
self.canvas = tk.Canvas(master)
self.frame = tk.Frame(self.canvas)
self.scrollbar = tk.Scrollbar(master, orient = 'vertical',
command = self.canvas.yview)
### scrollbar moves with current canvas scrollamount ###
self.canvas.configure(yscrollcommand = self.scrollbar.set)
self.scrollbar.pack(side = 'right', fill = 'y')
self.canvas.pack(side = 'left', fill = 'both', expand = True)
### creating frame to pack widgets onto ###
self.canvas.create_window((4, 4), window = self.frame,
anchor = 'nw', tags = 'self.frame')
### setting scrollbar height on load ###
self.frame.bind('<Configure>', self.frameConfig)
### scroll when a user's mouse wheel is used inside the canvas ###
def scrollCanvas(event):
self.canvas.yview_scroll(-1*(event.delta//120), 'units')
self.canvas.bind('<MouseWheel>', scrollCanvas)
### set the scrollregion of the canvas ###
def frameConfig(self, event):
self.canvas.configure(scrollregion = self.canvas.bbox('all'))
class OptionSet(tk.Frame):
def __init__(self, master, **kwargs):
super().__init__()
self.all = tk.Frame(master)
self.all.configure(bd = 1, relief = 'solid')
# independent label
self.text = '' if not kwargs['text'] else kwargs['text']
self.label = tk.Label(text = self.text)
# list of all buttons
self.buttons = tk.Frame()
buttons = [] if not kwargs['buttons'] else kwargs['buttons']
self.button_list = []
if buttons:
for button in buttons:
self.button_list.append(
tk.Button(self.buttons, text = button)
)
self.style()
def style(self, default = 1, **kwargs):
if default:
self.label.pack(in_ = self.all, side = 'left')
for button in self.button_list:
button.pack(side = 'left')
self.buttons.pack(in_ = self.all, side = 'right')
root = tk.Tk()
list_items = []
current = {
'month': 'August'
# ...
}
def btn_fcn(num):
for i in list_items:
i.grid_forget()
'''
# get event as input
event = sd.askstring('Event Input',
f"What is happening on {current['month']} {num}?")
# insert new list_item
list_items.append(OptionSet(event_list.frame, text = event,
buttons = ['Edit', 'Delete']))
print(event)
'''
for i in range(10):
list_items.append(OptionSet(event_list.frame, text = 'test',
buttons = ['Edit', 'Delete']))
for i in list_items:
i.all.grid(sticky = 'we')
tk.Button(root, text = 'Add', command = lambda: btn_fcn(22)).pack()
event_list = ScrollFrame(root)
event_list.pack()
root.mainloop()
我希望按钮和标签在 ScrollFrame 之外被切断。我不知道它们是否从框架或画布溢出,但如果一切按计划进行,它们应该正常切断。
谢谢。
解决方案
问题是您对创建小部件的位置非常草率。例如,您不是将画布和滚动条放在 ScrollFrame 中,而是将其放在master
. 中定义的每个小部件都需要ScrolLFrame
在.self
self
这同样适用OptionSet
- 您将内部框架 ( self.all
) 和其他小部件放入master
而不是放入OptionSet
自身。
我的建议是暂时删除所有OptionSet
代码(或者干脆不使用它),而是只在滚动框架中添加标签。专注于在没有将自定义类添加到自定义类的复杂性的情况下使其正常工作。一旦您能够只滚动标签,您就可以在OptionSet
代码中重新添加。
推荐阅读
- c - 使用 getopt optarg 的 fopen 错误问题
- power-automate - 在 Power Automate 中每月创建存储桶并在其中创建任务
- ms-word - 官员:在 .rmd 文件中插入横向格式的分节符
- spring - Springboot 后端无法连接来自 Vue 的 Axios 调用
- c# - WPF 打印问题:为什么我的 PageMediaSize 设置被忽略?
- python - 如何检查给定 DataFrame 列的每一行是否在指定范围内?
- python - 如何在类似 JSON 格式的文件中找到平均值?
- python - 如何通过简单的神经网络正确使用批处理 - 基本 Pytorch
- python - 为所有网格设置 xticklabels,用于使用使用 col_wrap 的 seaborn catplot 创建的图
- openlayers - Kinetica 热图未在某些地图尺寸上显示