绘图时无法更改拖放(使用 tkinterdnd2)光栅

问题描述 投票:0回答:1

运行以下Python代码时,我可以更改栅格(通过拖放新的栅格文件)并在新窗口中多次显示其名称(无需关闭选择窗口并重新运行代码)。但是一旦我绘制了栅格分布,我就无法再更改栅格文件。这就是我想要的。

import os
import tkinter as tk
from tkinterdnd2 import TkinterDnD, DND_FILES
import rasterio
import matplotlib.pyplot as plt
from tkinter import messagebox

class SimpleApp(TkinterDnD.Tk):
    def __init__(self):
        super().__init__()
        self.title("Simple File Selector")
        self.geometry("400x400")

        self.file_label = tk.Label(self, text="Drop a file here", relief="solid", width=40, height=5)
        self.file_label.pack(pady=20)
        self.file_label.drop_target_register(DND_FILES)
        self.file_label.dnd_bind('<<Drop>>', self.load_file)

        self.print_button = tk.Button(self, text="Display Filename", command=self.display_filename)
        self.print_button.pack(pady=20)

        self.plot_button = tk.Button(self, text="Plot Distribution", command=self.plot_distribution)
        self.plot_button.pack(pady=20)

    def load_file(self, event):
        self.file_path = event.data.strip('{}')
        self.file_label.config(text=os.path.basename(self.file_path) if self.file_path else "No file selected")
        try:
            with rasterio.open(self.file_path) as src:
                self.raster_data = src.read(1)
        except Exception as e:
            messagebox.showerror("Error", f"Failed to read raster file: {e}")
            self.file_label.config(text="Drop a file here")
            self.raster_data = None

    def display_filename(self):
        if hasattr(self, 'file_path') and self.file_path:
            filename_window = tk.Toplevel(self)
            filename_window.title("Selected File")
            filename_window.geometry("300x100")
            filename_label = tk.Label(filename_window, text=self.file_path, wraplength=280)
            filename_label.pack(pady=20)
        else:
            messagebox.showerror("Error", "No file selected")

    def plot_distribution(self):
        if hasattr(self, 'raster_data') and self.raster_data is not None:
            plt.figure()
            plt.hist(self.raster_data.flatten(), bins=50, color='blue', edgecolor='black')
            plt.title('Raster Data Distribution')
            plt.xlabel('Value')
            plt.ylabel('Frequency')
            plt.show()
        else:
            messagebox.showerror("Error", "No raster data to plot")

if __name__ == "__main__":
    app = SimpleApp()
    app.mainloop()
python-3.x matplotlib tkinter rasterio
1个回答
0
投票

受到TheLizzardlink的启发,我能够解决这个问题。谢谢他。

这是固定代码:

import os
import tkinter as tk
from tkinterdnd2 import TkinterDnD, DND_FILES
import rasterio
import matplotlib.pyplot as plt
from tkinter import messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.figure import Figure

class SimpleApp(TkinterDnD.Tk):
    def __init__(self):
        super().__init__()
        self.title("Simple File Selector")
        self.geometry("400x400")

        self.file_label = tk.Label(self, text="Drop a file here", relief="solid", width=40, height=5)
        self.file_label.pack(pady=20)
        self.file_label.drop_target_register(DND_FILES)
        self.file_label.dnd_bind('<<Drop>>', self.load_file)

        self.print_button = tk.Button(self, text="Display Filename", command=self.display_filename)
        self.print_button.pack(pady=20)

        self.plot_button = tk.Button(self, text="Plot Distribution", command=self.plot_distribution)
        self.plot_button.pack(pady=20)

        self.file_path = None
        self.raster_data = None

    def load_file(self, event):
        self.file_path = event.data.strip('{}')
        self.file_label.config(text=os.path.basename(self.file_path) if self.file_path else "No file selected")
        try:
            with rasterio.open(self.file_path) as src:
                self.raster_data = src.read(1)
        except Exception as e:
            messagebox.showerror("Error", f"Failed to read raster file: {e}")
            self.file_label.config(text="Drop a file here")
            self.raster_data = None

    def display_filename(self):
        if self.file_path:
            filename_window = tk.Toplevel(self)
            filename_window.title("Selected File")
            filename_window.geometry("300x100")
            filename_label = tk.Label(filename_window, text=self.file_path, wraplength=280)
            filename_label.pack(pady=20)
        else:
            messagebox.showerror("Error", "No file selected")

    def plot_distribution(self):
        if self.raster_data is not None:
            plot_window = tk.Toplevel(self)
            plot_window.title("Raster Data Distribution")
            plot_window.geometry("800x600")

            fig = Figure(figsize=(6, 4), dpi=100)
            ax = fig.add_subplot(111)
            ax.hist(self.raster_data.flatten(), bins=50, color='blue', edgecolor='black')
            ax.set_title('Raster Data Distribution')
            ax.set_xlabel('Value')
            ax.set_ylabel('Frequency')

            canvas = FigureCanvasTkAgg(fig, master=plot_window)
            canvas.draw()
            canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

            toolbar_frame = tk.Frame(plot_window)
            toolbar_frame.pack(side=tk.BOTTOM, fill=tk.X)
            toolbar = NavigationToolbar2Tk(canvas, toolbar_frame)
            toolbar.update()
            canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        else:
            messagebox.showerror("Error", "No raster data to plot")

if __name__ == "__main__":
    app = SimpleApp()
    app.mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.