英文:
Tkinter problem to get the values for more than one slider in a scrollable canvas
问题
我无法正确获取我在可滚动画布中创建的不同比例尺的值。
如果我移动滑块,它总是更改最后一个条目。
请告诉我是否有关于该代码的想法。
它打印出已更改的数字,但未放置在u[x]的正确位置。
打印示例:将第一个滑块更改为1
1 正确(print(val)) {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: '1'} false 应为(print(str(u)) {0: '1', 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}
import tkinter as tk
from tkinter import ttk
global II
label={}
scale={}
u={}
class Scrollable(tk.Frame):
def __init__(self, frame, width=32):
scrollbar = tk.Scrollbar(frame, width=width)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y, expand=False)
self.canvas = tk.Canvas(frame, yscrollcommand=scrollbar.set)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.config(command=self.canvas.yview)
self.canvas.bind('<Configure>', self.__fill_canvas)
# base class initialization
tk.Frame.__init__(self, frame)
# assign this obj (the inner frame) to the windows item of the canvas
self.windows_item = self.canvas.create_window(0,0, window=self, anchor=tk.NW)
def __fill_canvas(self, event):
canvas_width = event.width
self.canvas.itemconfig(self.windows_item, width = canvas_width)
def update(self):
print(scale)
self.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item))
root = tk.Tk()
body = ttk.Frame(root)
body.pack()
def print_value(val):
print(val)
u[II]=val
print(str(u))
scrollable_body = Scrollable(body, width=32)
#scrollable_body2 = Scrollable(body, width=32)
print(scrollable_body)
for II in range(10):
x={II:0}
u.update(x)
label[II]=tk.Label(scrollable_body, text="Hello "+str(II)).grid(column=0)
scale[II]=tk.Scale(scrollable_body, from_=-10, to=20,sliderlength=60, length=300, orient=tk.HORIZONTAL, command=print_value).grid(column=2)
scrollable_body.update()
root.mainloop()
英文:
I can not fetch the values correctly for the different scalebars I created in an scrollable canvas.
If I move the sliders it changes allways the last entry.
Please advise if you have ideas to that code.
It prints out the changed number but is not placed in the correct position of u[x]
Print out example changed first slider to 1
1 correct (print(val)) {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: '1'} false should be (print(str(u)) {0: '1', 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}
import tkinter as tk
from tkinter import ttk
global II
label={}
scale={}
u={}
class Scrollable(tk.Frame):
def __init__(self, frame, width=32):
scrollbar = tk.Scrollbar(frame, width=width)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y, expand=False)
self.canvas = tk.Canvas(frame, yscrollcommand=scrollbar.set)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.config(command=self.canvas.yview)
self.canvas.bind('<Configure>', self.__fill_canvas)
# base class initialization
tk.Frame.__init__(self, frame)
# assign this obj (the inner frame) to the windows item of the canvas
self.windows_item = self.canvas.create_window(0,0, window=self, anchor=tk.NW)
def __fill_canvas(self, event):
canvas_width = event.width
self.canvas.itemconfig(self.windows_item, width = canvas_width)
def update(self):
print(scale)
self.update_idletasks()
self.canvas.config(scrollregion=self.canvas.bbox(self.windows_item))
root = tk.Tk()
body = ttk.Frame(root)
body.pack()
def print_value(val):
print(val)
u[II]=val
print(str(u))
scrollable_body = Scrollable(body, width=32)
#scrollable_body2 = Scrollable(body, width=32)
print(scrollable_body)
for II in range(10):
x={II:0}
u.update(x)
label[II]=tk.Label(scrollable_body, text="Hello "+str(II)).grid(column=0)
scale[II]=tk.Scale(scrollable_body, from_=-10, to=20,sliderlength=60, length=300, orient=tk.HORIZONTAL, command=print_value).grid(column=2)
scrollable_body.update()
root.mainloop()
答案1
得分: 0
请注意,在for循环之后,变量II
将为9,因此在执行函数时,print_value()
内的u[II]
将与u[9]
相同。
其中一种解决方法是将lambda参数的默认值绑定到所需的值,如下所示:
def print_value(idx, val):
print(idx, val)
u[idx] = int(val)
print(u)
for II in range(10):
x={II:0}
u.update(x)
#u[II] = 0 # 实际上,上面两行可以替换为这行
label[II]=tk.Label(scrollable_body, text="Hello "+str(II))
label[II].grid(row=II, column=0)
scale[II]=tk.Scale(scrollable_body, from_=-10, to=20, sliderlength=60, length=300, orient=tk.HORIZONTAL,
# 使用参数的默认值来绑定所需的值,并将其传递给print_value()
command=lambda val, idx=II: print_value(idx, val))
scale[II].grid(row=II, column=2)
英文:
Note that variable II
will be 9 after the for loop, so u[II]
inside print_value()
will be the same as u[9]
when the function is executed.
One of the workaround is binding default value of lambda argument to the required value as below:
def print_value(idx, val):
print(idx, val)
u[idx] = int(val)
print(u)
for II in range(10):
x={II:0}
u.update(x)
#u[II] = 0 # the above two lines can be replaced by this line actually
label[II]=tk.Label(scrollable_body, text="Hello "+str(II))
label[II].grid(row=II, column=0)
scale[II]=tk.Scale(scrollable_body, from_=-10, to=20, sliderlength=60, length=300, orient=tk.HORIZONTAL,
# use default value of argument to bind the required value and pass it to print_value()
command=lambda val, idx=II: print_value(idx, val))
scale[II].grid(row=II, column=2)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论