python - 带有 tkinter 的非常长的清单框
问题描述
我正在使用此答案中的代码制作带有复选框的列表。
import tkinter as tk
root = tk.Tk()
class ChecklistBox(tk.Frame):
def __init__(self, parent, choices, **kwargs):
tk.Frame.__init__(self, parent, **kwargs)
self.vars = []
bg = self.cget("background")
for choice in choices:
var = tk.StringVar(value=choice)
self.vars.append(var)
cb = tk.Checkbutton(self, var=var, text=choice,
onvalue=choice, offvalue="",
anchor="w", width=20, background=bg,
relief="flat", highlightthickness=0
)
cb.pack(side="top", fill="x", anchor="w")
def getCheckedItems(self):
values = []
for var in self.vars:
value = var.get()
if value:
values.append(value)
return values
choices = [str(e) for e in range(100)]
checklist = ChecklistBox(root, choices, bd=1, relief="sunken", background="white")
checklist.pack()
由于选项列表很长,我想在此列表中添加一个滚动条。做这个的最好方式是什么 ?
我尝试按照此处的示例进行操作,但ChecklistBox
没有yview
方法,也没有yscrollcommand
选择。我不知道如何规避这个问题。
解决方案
问题的根源是框架不可滚动。因此,您必须找到一个支持滚动的小部件并将其用作向一组小部件添加滚动的基础。
小Canvas
部件通常用于此目的。它通常与内部框架一起使用,这使得它易于使用pack
或grid
排列小部件。但是,因为您正在创建相同小部件的垂直堆栈,所以直接在画布上绘制复选按钮会更容易。
第一步是在框架中添加画布和滚动条:
class ChecklistBox(tk.Frame):
def __init__(self, parent, choices, **kwargs):
tk.Frame.__init__(self, parent, **kwargs)
canvas = tk.Canvas(self, background=self.cget("background"))
vsb = tk.Scrollbar(self, command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
...
接下来,pack
我们将调用create_window
. 我们可以通过获取上一项的 y 坐标来确定下一项的放置位置。我们将使用pady
框架的选项来进行间距。
pady = int(str(self.cget("pady")))
for choice in choices:
...
bbox = canvas.bbox("all")
y0 = pady if bbox is None else bbox[3]+pady
canvas.create_window(0, y0, window=cb, anchor="nw")
最后,您需要确保scrollregion
设置正确:
canvas.configure(scrollregion=canvas.bbox("all"))
推荐阅读
- javascript - Rails 3.2 javascript 部分未操作 html 页面
- python-3.x - 使用 bs4 进行 Web 抓取:将结果附加到 csv 时,仅显示最后两个值
- qt - QNetworkAccessManager 使用 rtsp 链接
- xml - 在jmeter的XML响应中提取多次出现的相同字段
- python - Pandas:根据条件删除每组的行
- javascript - 请求的资源上存在 Access-Control-Allow-Origin 标头
- html - 如何使用 VH 布局保留部分?
- c# - 无限 PaintEvent 循环
- json - Laravel 原始 JSON 响应
- excel - 如何合并另一个工作表中的单元格?