Overhaul my script heavily:
```
import os
from io import BytesIO
from typing import Optional

import gi
import requests
from PIL import Image
from fastai.vision.all import load_learner, PILImage, Learner

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, GLib


class ImagePredictorApp(Gtk.Window):
    def __init__(self):
        super().__init__(title="Image Predictor")
        self.set_border_width(10)
        self.set_default_size(800, 600)  # Increased size to accommodate image preview

        # Initialize model attribute
        self.model: Optional[Learner] = None

        # Create UI components
        self.create_widgets()

    def create_widgets(self):
        """Set up the UI components and layout."""
        # Main layout container
        main_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)

        # Left side: Controls
        controls_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)

        # Load Model Section
        self.load_model_button = Gtk.Button(label="Load Model (.pkl or .pth)")
        self.load_model_button.connect("clicked", self.on_load_model)

        # Image Selection Section
        image_select_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
        self.image_entry = Gtk.Entry()
        self.image_entry.set_placeholder_text("Enter image path or URL")
        self.image_button = Gtk.Button(label="Select Image")
        self.image_button.connect("clicked", self.on_select_image)
        image_select_hbox.pack_start(self.image_entry, True, True, 0)
        image_select_hbox.pack_start(self.image_button, False, False, 0)

        # Threshold Slider Section
        self.threshold_label = Gtk.Label(label="Prediction Threshold: 50%")
        self.threshold_adjustment = Gtk.Adjustment(50, 0, 100, 1, 10, 0)
        self.threshold_slider = Gtk.Scale(
            orientation=Gtk.Orientation.HORIZONTAL,
            adjustment=self.threshold_adjustment
        )
        self.threshold_slider.set_digits(0)
        self.threshold_slider.connect("value-changed", self.on_threshold_changed)

        # Predict Button
        self.predict_button = Gtk.Button(label="Predict")
        self.predict_button.connect("clicked", self.on_predict)
        self.predict_button.set_sensitive(False)

        # Output Display
        self.output_label = Gtk.Label(label="Output will be shown here.")
        self.output_label.set_line_wrap(True)
        self.output_label.set_xalign(0)

        # Adding widgets to the controls VBox
        controls_vbox.pack_start(self.load_model_button, False, False, 0)
        controls_vbox.pack_start(image_select_hbox, False, False, 0)
        controls_vbox.pack_start(self.threshold_label, False, False, 0)
        controls_vbox.pack_start(self.threshold_slider, False, False, 0)
        controls_vbox.pack_start(self.predict_button, False, False, 0)
        controls_vbox.pack_start(self.output_label, False, False, 0)

        # Right side: Image Preview
        preview_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
        preview_label = Gtk.Label(label="Image Preview:")
        preview_label.set_xalign(0)
        self.image_preview = Gtk.Image()
        # Removed the set_max_size method as Gtk.Image does not support it
        preview_vbox.pack_start(preview_label, False, False, 0)
        preview_vbox.pack_start(self.image_preview, True, True, 0)

        # Adding both sections to the main HBox
        main_hbox.pack_start(controls_vbox, False, False, 0)
        main_hbox.pack_start(preview_vbox, True, True, 0)

        self.add(main_hbox)

    def on_load_model(self, button: Gtk.Button):
        """Handle the Load Model button click."""
        dialog = Gtk.FileChooserDialog(
            title="Choose a .pkl or .pth file",
            parent=self,
            action=Gtk.FileChooserAction.OPEN
        )
        dialog.add_buttons(
            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OPEN, Gtk.ResponseType.OK
        )
        dialog.set_filter(self.create_file_filter())

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            model_path = dialog.get_filename()
            self.load_model(model_path)
        dialog.destroy()

    def create_file_filter(self) -> Gtk.FileFilter:
        """Create a file filter for model files."""
        file_filter = Gtk.FileFilter()
        file_filter.set_name("Model Files")
        for pattern in ["*.pkl", "*.pth"]:
            file_filter.add_pattern(pattern)
        return file_filter

    def load_model(self, model_path: str):
        """Load the machine learning model from the specified path."""
        try:
            self.model = load_learner(model_path)
            self.predict_button.set_sensitive(True)
            self.output_label.set_text(f"Model loaded successfully from:\n{model_path}")
        except Exception as e:
            self.model = None
            self.predict_button.set_sensitive(False)
            self.output_label.set_text(f"Failed to load model:\n{e}")

    def on_select_image(self, button: Gtk.Button):
        """Handle the Select Image button click."""
        dialog = Gtk.FileChooserDialog(
            title="Choose an image",
            parent=self,
            action=Gtk.FileChooserAction.OPEN
        )
        dialog.add_buttons(
            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
            Gtk.STOCK_OPEN, Gtk.ResponseType.OK
        )
        dialog.set_filter(self.create_image_filter())

        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            image_path = dialog.get_filename()
            self.image_entry.set_text(image_path)
            self.display_image(image_path)
        dialog.destroy()

    def create_image_filter(self) -> Gtk.FileFilter:
        """Create a file filter for image files."""
        img_filter = Gtk.FileFilter()
        img_filter.set_name("Image Files")
        for pattern in ["*.png", "*.jpg", "*.jpeg", "*.webp"]:
            img_filter.add_pattern(pattern)
        img_filter.add_mime_type("image/png")
        img_filter.add_mime_type("image/jpeg")
        return img_filter

    def on_threshold_changed(self, scale: Gtk.Scale):
        """Update the threshold label when the slider value changes."""
        value = self.threshold_slider.get_value()
        self.threshold_label.set_text(f"Prediction Threshold: {value:.0f}%")

    def on_predict(self, button: Gtk.Button):
        """Handle the Predict button click."""
        if not self.model:
            self.output_label.set_text("Please load a model first.")
            return

        image_input = self.image_entry.get_text().strip()
        if not image_input:
            self.output_label.set_text("Please provide an image path or URL.")
            return

        try:
            image = self.load_image(image_input)
            self.display_image(image_input)  # Ensure image preview is updated
        except Exception as e:
            self.output_label.set_text(f"Error loading image:\n{e}")
            return

        try:
            pred, pred_idx, outputs = self.model.predict(image)
            probabilities = outputs.numpy() * 100  # Convert to percentage
            classes = self.model.dls.vocab  # Get class names
            threshold = self.threshold_slider.get_value()  # Get the threshold value

            # Prepare formatted prediction results
            output_lines = ["<b>Predictions:</b>"]
            for class_name, probability in zip(classes, probabilities):
                if probability >= threshold:
                    line = f"• {class_name}: {probability:.2f}%"
                    output_lines.append(line)
            output_lines.append(f"\n<b>Overall Prediction:</b> {pred}")

            # Update the output label using Pango Markup for better formatting
            markup_text = "\n".join(output_lines)
            self.output_label.set_markup(markup_text)

            # Optionally, print to terminal
            for line in output_lines:
                print(line)

        except Exception as e:
            self.output_label.set_text(f"Error during prediction:\n{e}")

    def load_image(self, image_input: str) -> PILImage:
        """
        Load an image from a local path or a URL.

        Args:
            image_input (str): The path or URL of the image.

        Returns:
            PILImage: The loaded image.
        """
        if image_input.startswith(('http://', 'https://', 'ftp://')):
            response = requests.get(image_input)
            response.raise_for_status()
            return PILImage.create(BytesIO(response.content))
        elif os.path.isfile(image_input):
            return PILImage.create(image_input)
        else:
            raise ValueError("Invalid image path or URL.")

    def display_image(self, image_input: str):
        """
        Display the selected image in the image preview widget.

        Args:
            image_input (str): The path or URL of the image.
        """
        try:
            if image_input.startswith(('http://', 'https://', 'ftp://')):
                response = requests.get(image_input)
                response.raise_for_status()
                loader = GdkPixbuf.PixbufLoader.new()
                loader.write(response.content)
                loader.close()
                pixbuf = loader.get_pixbuf()
            else:
                pixbuf = GdkPixbuf.Pixbuf.new_from_file(image_input)

            # Scale the pixbuf to fit within 400x400 while preserving aspect ratio
            scaled_pixbuf = pixbuf.scale_simple(
                400, 400, GdkPixbuf.InterpType.BILINEAR
            )
            self.image_preview.set_from_pixbuf(scaled_pixbuf)
        except Exception as e:
            # If there's an error loading the image, clear the preview and notify the user
            self.image_preview.set_from_icon_name("image-missing", Gtk.IconSize.DIALOG)
            self.output_label.set_text(f"Failed to display image preview:\n{e}")


def main():
    """Initialize and run the GTK application."""
    app = ImagePredictorApp()
    app.connect("destroy", Gtk.main_quit)
    app.show_all()
    Gtk.main()


if __name__ == "__main__":
    main()```