简体   繁体   中英

Python Tkinter Canvas' border overlap with window create by `create_window'

I am using tkinter to make a scrolled canvas. When I create a window by create_window link with a frame which is bigger then the canvas, the window will overlap with the border of canvas.

import Tkinter as tk


class ScrollCanvas(object):
    """A widget to show table in frame"""
    def __init__(self, parent=None):
        self.parent = parent
        self.frame = tk.Frame(self.parent, bd=3,
                              relief=tk.GROOVE)
        self.frame.pack(fill=tk.BOTH, expand=1)

        self.frame.grid_rowconfigure(0, weight=1)
        self.frame.grid_columnconfigure(0, weight=1)

        self.xscrollbar = tk.Scrollbar(self.frame, orient=tk.HORIZONTAL)
        self.yscrollbar = tk.Scrollbar(self.frame, orient=tk.VERTICAL)
        self.canvas = tk.Canvas(self.frame, bg='#006666',
                                bd=10, relief=tk.GROOVE,
                                xscrollcommand=self.xscrollbar.set,
                                yscrollcommand=self.yscrollbar.set)

        self.xscrollbar.grid(row=1, column=0, sticky=tk.W+tk.E)
        self.yscrollbar.grid(row=0, column=1, sticky=tk.N+tk.S)
        self.canvas.grid(row=0, column=0, sticky=tk.W+tk.E+tk.N+tk.S)

        self.xscrollbar.config(command=self.canvas.xview)
        self.yscrollbar.config(command=self.canvas.yview)

        self.table = tk.Frame(self.canvas, bd=5, relief=tk.SOLID,
                              width=400, height=200)

        self.canvas.create_window(0, 0, anchor=tk.CENTER, window=self.table)
        self.canvas.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox(tk.ALL))


def main():
    app = tk.Tk()
    app.geometry('400x300')
    frame = tk.Frame(app, width=50, height=50)
    frame.propagate(0)
    frame.pack(fill=tk.BOTH, expand=1)
    mytable = ScrollCanvas(parent=frame)
    app.mainloop()

main()

The result is like this:(the red box)

在此处输入图片说明

Does anyone know how to fix this?

Oddly, the canvas border is part of the drawing space, so anything drawn on the canvas has the potential to overlap the borders.

The solution that I use is to remove the border from the canvas, and then put the canvas inside a frame that has a border. Visually it looks the same, but because the visible border belongs to another widget it is impossible for items in the canvas to overlap it.

You can solve that problem by setting the state to be hidden and when it's needed to set it back to normal like this

import tkinter

...
...

canvas = tkinter.Canvas(self, width=100, height=100, bd=0, highlightthickness=0)
canvas.pack()

btn = tkinter.Button(text="Click me", command=print)

win = canvas.create_window(10, 10, anchor=tkinter.NW, window=btn)

canvas.itemconfigure(win, state=tkinter.HIDDEN)

...
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM