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

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()

关键修改说明

  1. 新增内部容器Frame
    在可滚动画布item_canvas内创建inner_frame,所有图片都放入该容器,并通过create_window绑定到画布上,确保滚动操作能带动图片区域移动。
  2. 修正图片挂载目标
    将FigureCanvasTkAgg的挂载目标从root改为inner_frame,让图片属于可滚动区域的一部分。
  3. 改用网格布局替代place
    用grid按每行2个的规则排列图片,避免手动计算坐标的混乱,布局更稳定。
  4. 动态计算滚动范围
    图片加载完成后,更新内部容器尺寸,再用bbox("all")获取内容实际大小,设置为滚动区域,保证滚动范围准确。
  5. 修复路径读取问题
    读取txt内容时添加.strip(),避免换行符导致路径解析错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:35:18