在 tkinter canvas 对象的查看区域周围创建 "barriers"
Creating "barriers" around the viewing area of a tkinter canvas object
好的,所以我这里的情况有点特殊,所以请耐心等待。我希望能够在 tkinter canvas 的 查看区域 (用户可见的 canvas 部分)周围创建所谓的 "barriers" ] 目的。例如,看看下面的屏幕截图(基于最后的 MCVE):
正如您在上图中所看到的,这条线目前在canvas的可视区域之外canvas用户到达终点。然而,这不是我想要的。 相反,我希望每当用户到达 canvas 可见区域的尽头时,"barrier" 变热, 并在联系时,出现一个马车return,并且线路从那里继续。所以我真正想要的不是上面的,而是这个:
上面的截图是我用的MCVE:
import tkinter as TK
xold = None
yold = None
class canvas(TK.Frame):
def __init__(self, root, *args, **kwargs):
# Initialize a tkinter frame widget
TK.Frame.__init__(self, root, width = 800, height = 850, *args, **kwargs)
self.root = self.winfo_toplevel()
self.bg = "white"
self.width, self.height = 850, 800
self.canvwidth, self.canvheight = 10000, 10000
# Set up the canvas and its corresponding scrollbars
self.canvas = TK.Canvas(root, width=850, height=800,
bg=self.bg, borderwidth=0, highlightthickness = 5, highlightbackground = 'brown', highlightcolor = 'brown')
self.hscroll = TK.Scrollbar(root, command=self.canvas.xview,
orient=TK.HORIZONTAL)
self.vscroll = TK.Scrollbar(root, command=self.canvas.yview)
self.canvas.configure(xscrollcommand=self.hscroll.set,
yscrollcommand=self.vscroll.set)
self.rowconfigure(0, weight=1, minsize=0)
self.columnconfigure(0, weight=1, minsize=0)
# Add the scrollbars into the root window
self.canvas.grid(padx=1, pady=1, row=0,
column=0, rowspan=1, columnspan=1, sticky = 'news')
self.vscroll.grid(padx=1, pady=1, row=0,
column=1, rowspan=1, columnspan=1, sticky='news')
self.hscroll.grid(padx=1, pady=1, row=1,
column=0, rowspan=1, columnspan=1, sticky='news')
# Call the `reset` method of the canvas class
self.reset()
# Bind the `line` method to the 'l' key of the users keyboard (as an example of what I want)
self.root.bind('<l>', self.line)
def reset(self, canvwidth=None, canvheight=None, bg = None):
###############################################################################################################################
# This adds the scrollbars themselves to the canvas and adapts them to the canvas's size (in this case, 10000 x 10000 pixels) #
###############################################################################################################################
if canvwidth:
self.canvwidth = canvwidth
if canvheight:
self.canvheight = canvheight
if bg:
self.bg = bg
self.canvas.config(bg=bg,
scrollregion=(-self.canvwidth//2, -self.canvheight//2,
self.canvwidth//2, self.canvheight//2))
self.canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
self.canvwidth)
self.canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
self.canvheight)
def line(self, event):
########################################################################################################
# Create a short, horizontal, black line on every press of the user's 'l' key (as an example to go by) #
########################################################################################################
global xold, yold
if xold != None and yold != None:
pass
else:
xold, yold = 0, 0
self.canvas.create_line(xold, yold, xold+30, yold, smooth = TK.TRUE, width = 1, capstyle = TK.ROUND, joinstyle = TK.ROUND, fill = 'black')
xold = xold+30
yold = yold
if __name__ == '__main__':
# Create a window, and provide that window to the canvas class as the root window
root = TK.Tk()
root.geometry('900x850')
canvas(root)
root.mainloop()
是否可以使用 tkinter 将此功能添加到上面的 MCVE 中?如果是这样,我将如何开始尝试实施它?
我不确定您实际上想做什么(尤其是在您提供非常大的 canvas 滚动条时试图限制显示区域中的绘图)。
对于最简单的情况,您只需要一个绑定值并针对它xold
进行测试
if xold > 440:
xold = -410
yold += 30
如果要考虑当前显示的区域,则必须结合canvas scrollregion
和xview
方法的信息。第一个 return canvas 的边界和前一个显示区域在 scrollregion 中的相对位置。
scroll = list(map(int,self.canvas["scrollregion"].split()))
xview = self.canvas.xview()
leftbound = scroll[0] + xview[1] * (scroll[2]-scroll[0])
if xold > leftbound:
rightbound = scroll[0] + xview[0] * (scroll[2]-scroll[0])
xold = rightbound
yold += 30
好的,所以我这里的情况有点特殊,所以请耐心等待。我希望能够在 tkinter canvas 的 查看区域 (用户可见的 canvas 部分)周围创建所谓的 "barriers" ] 目的。例如,看看下面的屏幕截图(基于最后的 MCVE):
正如您在上图中所看到的,这条线目前在canvas的可视区域之外canvas用户到达终点。然而,这不是我想要的。 相反,我希望每当用户到达 canvas 可见区域的尽头时,"barrier" 变热, 并在联系时,出现一个马车return,并且线路从那里继续。所以我真正想要的不是上面的,而是这个:
上面的截图是我用的MCVE:
import tkinter as TK
xold = None
yold = None
class canvas(TK.Frame):
def __init__(self, root, *args, **kwargs):
# Initialize a tkinter frame widget
TK.Frame.__init__(self, root, width = 800, height = 850, *args, **kwargs)
self.root = self.winfo_toplevel()
self.bg = "white"
self.width, self.height = 850, 800
self.canvwidth, self.canvheight = 10000, 10000
# Set up the canvas and its corresponding scrollbars
self.canvas = TK.Canvas(root, width=850, height=800,
bg=self.bg, borderwidth=0, highlightthickness = 5, highlightbackground = 'brown', highlightcolor = 'brown')
self.hscroll = TK.Scrollbar(root, command=self.canvas.xview,
orient=TK.HORIZONTAL)
self.vscroll = TK.Scrollbar(root, command=self.canvas.yview)
self.canvas.configure(xscrollcommand=self.hscroll.set,
yscrollcommand=self.vscroll.set)
self.rowconfigure(0, weight=1, minsize=0)
self.columnconfigure(0, weight=1, minsize=0)
# Add the scrollbars into the root window
self.canvas.grid(padx=1, pady=1, row=0,
column=0, rowspan=1, columnspan=1, sticky = 'news')
self.vscroll.grid(padx=1, pady=1, row=0,
column=1, rowspan=1, columnspan=1, sticky='news')
self.hscroll.grid(padx=1, pady=1, row=1,
column=0, rowspan=1, columnspan=1, sticky='news')
# Call the `reset` method of the canvas class
self.reset()
# Bind the `line` method to the 'l' key of the users keyboard (as an example of what I want)
self.root.bind('<l>', self.line)
def reset(self, canvwidth=None, canvheight=None, bg = None):
###############################################################################################################################
# This adds the scrollbars themselves to the canvas and adapts them to the canvas's size (in this case, 10000 x 10000 pixels) #
###############################################################################################################################
if canvwidth:
self.canvwidth = canvwidth
if canvheight:
self.canvheight = canvheight
if bg:
self.bg = bg
self.canvas.config(bg=bg,
scrollregion=(-self.canvwidth//2, -self.canvheight//2,
self.canvwidth//2, self.canvheight//2))
self.canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
self.canvwidth)
self.canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
self.canvheight)
def line(self, event):
########################################################################################################
# Create a short, horizontal, black line on every press of the user's 'l' key (as an example to go by) #
########################################################################################################
global xold, yold
if xold != None and yold != None:
pass
else:
xold, yold = 0, 0
self.canvas.create_line(xold, yold, xold+30, yold, smooth = TK.TRUE, width = 1, capstyle = TK.ROUND, joinstyle = TK.ROUND, fill = 'black')
xold = xold+30
yold = yold
if __name__ == '__main__':
# Create a window, and provide that window to the canvas class as the root window
root = TK.Tk()
root.geometry('900x850')
canvas(root)
root.mainloop()
是否可以使用 tkinter 将此功能添加到上面的 MCVE 中?如果是这样,我将如何开始尝试实施它?
我不确定您实际上想做什么(尤其是在您提供非常大的 canvas 滚动条时试图限制显示区域中的绘图)。
对于最简单的情况,您只需要一个绑定值并针对它xold
进行测试
if xold > 440:
xold = -410
yold += 30
如果要考虑当前显示的区域,则必须结合canvas scrollregion
和xview
方法的信息。第一个 return canvas 的边界和前一个显示区域在 scrollregion 中的相对位置。
scroll = list(map(int,self.canvas["scrollregion"].split()))
xview = self.canvas.xview()
leftbound = scroll[0] + xview[1] * (scroll[2]-scroll[0])
if xold > leftbound:
rightbound = scroll[0] + xview[0] * (scroll[2]-scroll[0])
xold = rightbound
yold += 30