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

Tkinter Canvas滚动区域图形绘制失效问题求助

问题:Tkinter Canvas滚动后无法绘制图形

我用Python Tkinter开发GUI程序,给Canvas组件添加了滚动条以查看未显示区域,实现了以下功能:

  • 绘制点状网格
  • 鼠标悬停网格点时显示虚线圆
  • 点击时绘制实心圆
  • 输出调试信息

初始可见区域的功能完全正常,但滚动后发现:点击、悬停事件能正常触发(调试信息可输出),但Canvas上的图形无法绘制显示。我无法理解为何初始区域的图形绘制、事件绑定均正常,滚动区域却无法渲染图形,怀疑是滚动条与Canvas的交互问题。


原始Canvas与滚动条初始化代码

def __init__(self, parent, model, settings, *args, **kwargs):
    super().__init__(parent, *args, **kwargs)       
    self.width = 625
    self.height = 500
    self.canvas = tk.Canvas(self, width=self.width, height=self.height, background='white', cursor='arrow')
    self.canvas.grid(row=0, column=0)

    self.focusDotImage = -1
    print("self.focusDotImage: ", self.focusDotImage)

    # 配置滚动区域
    self.canvas.configure(scrollregion=(0, 0, self.width * 2, self.height * 2))

    # 创建滚动条并关联Canvas
    xScroll = tk.Scrollbar(
        self,
        command=self.canvas.xview,
        orient=tk.HORIZONTAL
    )
    xScroll.grid(row=1, column=0, sticky='new')

    yScroll = tk.Scrollbar(self, command=self.canvas.yview)
    yScroll.grid(row=0, column=1, sticky='nsw')

    self.canvas.configure(yscrollcommand=yScroll.set)
    self.canvas.configure(xscrollcommand=xScroll.set)

    # 绘制点状网格
    self.space = 25
    self.dotRadius= 1
    self.nodeRadius = 5
    for i in range(0, self.width):
        for j in range(0, self.height):
            dotItem = self.canvas.create_rectangle(i * self.space-self.dotRadius, j * self.space-self.dotRadius, i * self.space + self.dotRadius,
                                                   j * self.space + self.dotRadius, fill='lightgrey')
            self.canvas.tag_bind(dotItem, '<Enter>', self._on_dot_enter)
            self.canvas.tag_bind(dotItem, '<Leave>', self._on_dot_leave)

    self.canvas.bind('<Button-1>', self._on_click)

复现问题的演示代码

import tkinter as tk

def _on_click(event):
    print("点击了图形元素...")
    global image_item3
    canvas.delete(image_item3)

def _on_click_canvas(e):
    print("坐标 {}, {}".format(e.x, e.y))
    canvas.create_oval(e.x, e.y, (e.x+10), (e.y+10), fill='white')

# 创建根窗口和Canvas
root = tk.Tk()

width = 1024
height = 768

canvas = tk.Canvas(
    root, background='black',
    width=width, height=height,
)
canvas.grid(row=0, column=0)

image_item = canvas.create_oval((200, 200), (300, 300), fill='white')
image_item2 = canvas.create_oval((300, 300), (400, 400), fill='white')
global image_item3
image_item3 = canvas.create_oval((200, 900), (300, 1000), fill='white')
canvas.tag_bind(image_item3, '<Button-1>', _on_click)
canvas.bind('<Button-1>', _on_click_canvas)

# 配置滚动区域
canvas.configure(scrollregion=(0, 0, width * 2, height * 2))

# 创建滚动条并关联Canvas
xscroll = tk.Scrollbar(
    root,
    command=canvas.xview,
    orient=tk.HORIZONTAL
)
xscroll.grid(row=1, column=0, sticky='new')

yscroll = tk.Scrollbar(root, command=canvas.yview)
yscroll.grid(row=0, column=1, sticky='nsw')

canvas.configure(yscrollcommand=yscroll.set)
canvas.configure(xscrollcommand=xscroll.set)

root.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:25:17