You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tkinter中阻止Canvas组件被选中?

解决Tkinter Canvas滚动框架中选中矩形的问题

当用Canvas实现滚动框架并在其中添加Entry组件时,切换焦点会导致Canvas周围出现深灰色选中边框,破坏界面美观。以下是两种直接有效的解决方法:

方案一:直接移除高亮边框

在初始化Canvas时添加highlightthickness=0参数,彻底关闭焦点高亮边框的绘制:

canvas = tk.Canvas(self, takefocus=0, highlightthickness=0)

方案二:隐藏高亮颜色(保留机制)

如果不想完全移除高亮机制,可以将高亮颜色设置为与Canvas背景色一致,让边框视觉上不可见:

canvas = tk.Canvas(self, takefocus=0, highlightcolor=self.cget("bg"))

修改后的完整示例代码

###########
# Imports #
###########

import tkinter as tk
from tkinter import ttk

#########
# Class #
#########

class ScrollableFrame(ttk.Frame):
    def __init__(self, container, *args, **kwargs):
        super().__init__(container, *args, **kwargs)
        # 添加highlightthickness=0消除选中边框
        canvas = tk.Canvas(self, takefocus=0, highlightthickness=0)
        self.canvas = canvas
        scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
        self.scrollable_frame = ttk.Frame(canvas, takefocus=0)
        self.scrollable_frame.columnconfigure(index=0, weight=1)

        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(
                scrollregion=canvas.bbox("all")
            )
        )

        self.scrollable_frame_id = canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")

        canvas.configure(yscrollcommand=scrollbar.set)
        self.canvas.bind('<Configure>', self.on_width_change)

        canvas.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")
        
    def on_mousewheel(self, event):
        shift = (event.state & 0x1) != 0
        scroll = -1 if event.delta > 0 else 1
        if shift:
            self.canvas.xview_scroll(scroll, "units")
        else:
            self.canvas.yview_scroll(scroll, "units")

    def on_width_change(self, event):
        canvas_width = event.width
        self.canvas.itemconfig(self.scrollable_frame_id, width=canvas_width * 0.99)

    def bind_tree(self, event, callback, widget=None):
        """
        Binds an event to a widget and all its descendants.
        """

        if widget is None:
            widget = self

        if isinstance(widget, ttk.Combobox):
            return

        widget.bind(event, callback, "")

        for child in widget.children.values():
            self.bind_tree(widget=child, event=event, callback=callback)

    def bind_list(self, widgets, event, callback):
        for widget in widgets:
            self.bind_tree(widget=widget, event=event, callback=callback)

    def set_mouse_scroll_on_list(self, widgets):
        self.bind_list(widgets, "<MouseWheel>", self.on_mousewheel)


###########
# Process #
###########

root = tk.Tk()

frame = ScrollableFrame(root)
frame.grid(row=0,column=0,sticky="nsew")

entry = ttk.Entry(frame.scrollable_frame)
entry.pack()

root.mainloop()

修改后,切换Entry焦点时Canvas周围的深灰色选中矩形会消失,滚动框架的功能不受任何影响。

内容的提问来源于stack exchange,提问作者Paul Creusy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:13:18