【问题标题】:Creating "barriers" around the viewing area of a tkinter canvas object在 tkinter 画布对象的查看区域周围创建“障碍”
【发布时间】:2016-07-06 17:15:52
【问题描述】:

好的,所以我这里的情况有点特殊,请耐心等待。我希望能够在 tkinter 画布对象的 查看区域(用户可见的画布部分)周围创建所谓的“屏障”。例如,看看下面的截图(基于最后的 MCVE):

正如您在上图中所见,当用户到达终点时,这条线当前会超出画布的查看区域。但是,这不是我想要的。相反,我希望每当用户到达画布可见区域的末端时,“障碍”就会变热,并且在接触时,回车发生,并且行从那里继续。所以我真正想要的不是上面的,而是这样的:

这是我用来截取上述截图的 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 中?如果是这样,我将如何开始尝试实施它?

【问题讨论】:

    标签: python tkinter newline python-3.5 tkinter-canvas


    【解决方案1】:

    我不确定您实际上要做什么(尤其是在您提供带有滚动条的非常大的画布时试图限制显示区域中的绘图)。

    对于最简单的情况,您只需要一个绑定值并针对它测试xold

    if xold > 440:
        xold = -410
        yold += 30
    

    如果要考虑当前显示区域,则必须结合画布scrollregionxview 方法中的信息。第一个返回画布的边界和前一个显示区域在滚动区域中的相对位置。

        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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      • 2014-08-17
      相关资源
      最近更新 更多