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")
替换它,然后从计算绘图宽度的结果。
在我的原始代码中,我正在做类似下面的事情,只是用了更多的数学。
它有效,但我不喜欢这样我可以看到我的滚动条 (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")
替换它,然后从计算绘图宽度的结果。