Python编写的GeoTiff迷你图库滚动功能失效问题排查请求
问题修复:GeoTiff迷你图库滚动功能失效
核心问题
你的代码中,滚动条控制的item_canvas与GeoTIFF图片完全分离——所有matplotlib生成的图片画布都直接挂载到了主窗口root上,而非你创建的可滚动画布区域内,导致滚动操作无法影响图片位置。
修复后的完整代码
import tkinter as tk import glob from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure import rasterio as rio from rasterio.plot import show SIZE_X = 100 SIZE_Y = 100 class Icon: def __init__(self, root): self.root = root self.root.title("GeoTIFF Mini Gallery") # 绑定滚动条与可滚动画布 self.ybar = tk.Scrollbar(self.root) self.item_canvas = tk.Canvas(self.root, width=354, height=401, yscrollcommand=self.ybar.set) self.ybar.configure(command=self.item_canvas.yview) # 创建内部容器Frame,所有图片都放入该容器 self.inner_frame = tk.Frame(self.item_canvas) self.item_canvas.create_window((0, 0), window=self.inner_frame, anchor="nw") self.ybar.pack(side=tk.RIGHT, fill=tk.Y) self.item_canvas.pack(side=tk.LEFT, expand=tk.TRUE, fill=tk.BOTH) self.get_icons() # 动态设置滚动区域为内部容器的实际大小 self.inner_frame.update_idletasks() self.item_canvas.configure(scrollregion=self.item_canvas.bbox("all")) def get_dir(self): link = r'work_dir/*.txt' with open(link) as f: self.file_photo = f.read().strip() # 移除换行符避免路径错误 self.link_to_dir = glob.glob(self.file_photo.rsplit('/', 1)[0] + '/*.tif') self.number = len(self.link_to_dir) def get_icons(self): '''生成迷你图库''' self.get_dir() FIGSIZE = 2.5 dpi = 60 img_width = int(FIGSIZE * dpi) img_height = int(FIGSIZE * dpi) padding = 10 # 图片间距 if self.number == 0: tk.Label(self.inner_frame, text='未找到TIFF文件').grid(row=0, column=0, padx=padding, pady=padding) return # 按每行2个的网格布局排列图片 for idx, tiff_path in enumerate(self.link_to_dir): row = idx // 2 col = idx % 2 fig = Figure(figsize=(FIGSIZE, FIGSIZE), dpi=dpi) # 将图片画布挂载到内部容器,而非主窗口 canvasGeo = FigureCanvasTkAgg(fig, master=self.inner_frame) canvas_widget = canvasGeo.get_tk_widget() canvas_widget.grid(row=row, column=col, padx=padding, pady=padding) with rio.open(tiff_path) as src_plot: show(src_plot, ax=fig.add_subplot()) canvasGeo.draw() if __name__ == '__main__': root = tk.Tk() Icon(root) root.mainloop()
关键修改说明
- 新增内部容器Frame
在可滚动画布item_canvas内创建inner_frame,所有图片都放入该容器,并通过create_window绑定到画布上,确保滚动操作能带动图片区域移动。 - 修正图片挂载目标
将FigureCanvasTkAgg的挂载目标从root改为inner_frame,让图片属于可滚动区域的一部分。 - 改用网格布局替代place
用grid按每行2个的规则排列图片,避免手动计算坐标的混乱,布局更稳定。 - 动态计算滚动范围
图片加载完成后,更新内部容器尺寸,再用bbox("all")获取内容实际大小,设置为滚动区域,保证滚动范围准确。 - 修复路径读取问题
读取txt内容时添加.strip(),避免换行符导致路径解析错误。
内容的提问来源于stack exchange,提问作者user20207408
相关产品推荐
相关产品推荐

