Tkinter问题:在可滚动的画布中获取多个滑块的值

huangapple go评论86阅读模式
英文:

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(&#39;&lt;Configure&gt;&#39;, 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=&quot;Hello &quot;+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=&quot;Hello &quot;+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)

huangapple
  • 本文由 发表于 2023年6月15日 20:58:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76482737.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定