如何实现GUI按钮选择图片文件后在新窗口中显示?
Fixing Your Tkinter Image Viewer Code
Got it, let's get your code working properly—right now it's just launching a file picker but not actually displaying the selected image in a new window. Let's walk through the fixes and the complete working version:
First, let's spot the issues in your original code:
- You created two Tk instances (
window = tk.Tk()anda = Tk())—this causes weird Tkinter behavior, we only need one main window. - The
openimgfilefunction only selects a file but doesn't load or display the image. - Using
filedialog.askopenfile()returns a file object, but we need the file path to load the image with PIL, soaskopenfilename()is better here. - When you do
button1 = Button(...).pack(),button1ends up asNone(sincepack()returns nothing)—it's cleaner to separate widget creation and layout.
Here's the corrected, working code:
import tkinter as tk from tkinter import filedialog from PIL import Image, ImageTk import os # Only one main window—no duplicates! root = tk.Tk() root.title("Pattern Matching") root.minsize(200, 200) def open_and_display_image(): # Get current working directory as starting point currdir = os.getcwd() # Ask user to select an image file, get the file path file_path = filedialog.askopenfilename( initialdir=currdir, title="Select an Image", filetypes=( ("PNG Files", "*.png"), ("JPEG Files", "*.jpg;*.jpeg"), ("All Files", "*.*") ) ) # If user cancels the dialog, do nothing if not file_path: return # Load the image with PIL try: image = Image.open(file_path) # Optional: Resize image if it's too big (adjust max size as needed) max_dimension = 800 width, height = image.size if width > max_dimension or height > max_dimension: ratio = min(max_dimension/width, max_dimension/height) image = image.resize((int(width*ratio), int(height*ratio)), Image.Resampling.LANCZOS) # Create a new top-level window to display the image img_window = tk.Toplevel(root) img_window.title("Image Preview") # Convert PIL image to Tkinter-compatible format tk_image = ImageTk.PhotoImage(image) # Create a label to hold the image and pack it img_label = tk.Label(img_window, image=tk_image) img_label.image = tk_image # Keep a reference to avoid garbage collection img_label.pack(padx=10, pady=10) except Exception as e: # Show error if image can't be loaded error_window = tk.Toplevel(root) error_window.title("Error") tk.Label(error_window, text=f"Could not load image:\n{str(e)}").pack(padx=20, pady=20) # Create button and layout separately open_button = tk.Button(root, text="Open File", width=10, height=2, command=open_and_display_image) open_button.pack(pady=50) root.mainloop()
Key improvements explained:
- Single main window: We use
root = tk.Tk()as the only main application window to prevent Tkinter conflicts. - Image loading & display: The
open_and_display_imagefunction now:- Gets the file path with
askopenfilename() - Uses PIL to load and optionally resize the image (so huge images don't break the window)
- Creates a new
Toplevelwindow to show the image - Converts the PIL image to
ImageTk.PhotoImageand keeps a reference to it (critical—otherwise Tkinter garbage collects the image and it won't show up)
- Gets the file path with
- Error handling: Added a try/except block to catch issues like invalid image files, so the app doesn't crash silently.
- Cleaner button setup: Separated button creation and
pack()so we can reference the button later if needed.
内容的提问来源于stack exchange,提问作者user11185769
相关产品推荐
相关产品推荐

