Canvas 项目宽度与滚动区域的宽度相关

Canvas item width related to the width of scrollregion

在我的原始代码中,我正在做类似下面的事情,只是用了更多的数学。

它有效,但我不喜欢这样我可以看到我的滚动条 (hscrbar) 的拇指如何在我计算 [=12] 中的宽度时从位置 0 移动到 1 =] 我的长方形。 因为在我的原始代码中,每次添加内容时我都需要查看它。

目前我还没有解决这个问题的想法,您可能知道解决方案。

import tkinter as tk

root = tk.Tk()


class my_figure(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.master = master
        self.root = self.winfo_toplevel()

        # DownFrame
        self.button = tk.Button(self, text='add', command=self.add)
        self.button.grid(column=0, row=0)
        self.body = tk.Frame(self, relief='sunken')
        self.hscrbar = tk.Scrollbar(self.body, orient=tk.HORIZONTAL)
        self.vscrbar = tk.Scrollbar(self.body)
        self.Display = tk.Canvas(self.body,
                                 xscrollcommand=self.hscrbar.set,
                                 yscrollcommand=self.vscrbar.set)
        self.hscrbar.config(command=self.Display.xview)
        
        self.body.grid(column=0, row=1, sticky='nswe')
        self.vscrbar.grid(column=1,sticky='ns')
        self.hscrbar.grid(row=1, column=0, sticky='we')
        self.Display.grid(column=0, row=0,
                          sticky='nswe')
        self.vscrbar.config(command=self.Display.yview)
        self.hscrbar.config(command=self.Display.xview)

        self.x = tk.IntVar()
        self.y = tk.IntVar()
        self.x.set(10)
        self.y.set(10)
        self.height = 10
    def add(self):
        self.Display.create_rectangle(self.x.get(),self.y.get(),self.get_width(),self.height)
        self.old_x = self.x.get()
        self.old_y = self.y.get()
        self.x.set(self.old_x+40)
        self.y.set(self.old_y+20)
        self.Display.config(scrollregion=self.Display.bbox("all"))

    def get_width(self):
        if self.hscrbar.get()[0] == 0 and self.hscrbar.get()[1] == 1: #if scrollbar shows everything
            return self.Display.winfo_width()#return width of the canvas
        else:
            self.Display.xview_moveto(0) #scrollbar at postition 0
            self.root.update_idletasks() #update idletasks to get correct value
            value = self.Display.winfo_width()-round(self.Display.winfo_width()*self.hscrbar.get()[1])
            width = value+self.Display.winfo_width() #calculate the width
            self.Display.xview_moveto(1) #move to position 1 to show my the end of rectangel
            return width


figure = my_figure(root)
figure.grid()
root.mainloop()

我的猜测是问题主要是由于您在 get_width 内部移动滚动条,调用 update_idletasks,然后再次移动滚动条。对 update_idletasks 的调用导致 window 重绘。重绘意味着你会看到滚动条向左移动,然后当函数完成时它会向右移动。

尚不完全清楚 get_width 应该做什么,但我猜您可以删除所有代码并用 self.Display.bbox("all") 替换它,然后从计算绘图宽度的结果。