diff --git a/__pycache__/image_canvas.cpython-312.pyc b/__pycache__/image_canvas.cpython-312.pyc index 0657195..44ef74a 100644 Binary files a/__pycache__/image_canvas.cpython-312.pyc and b/__pycache__/image_canvas.cpython-312.pyc differ diff --git a/__pycache__/metaview_logic.cpython-312.pyc b/__pycache__/metaview_logic.cpython-312.pyc new file mode 100644 index 0000000..5fe410f Binary files /dev/null and b/__pycache__/metaview_logic.cpython-312.pyc differ diff --git a/helpers.py b/helpers.py deleted file mode 100644 index 0226afb..0000000 --- a/helpers.py +++ /dev/null @@ -1,25 +0,0 @@ -# helpers.py -from PySide6.QtGui import QPixmap - -def load_image(path: str) -> QPixmap: - """ - Load an image from disk and return a QPixmap. - In the future, this can also handle scaling, caching, etc. - """ - pixmap = QPixmap(path) - if pixmap.isNull(): - raise FileNotFoundError(f"Could not load image: {path}") - return pixmap - - -def get_fake_metadata(path: str) -> dict: - """ - Temporary stub: returns fake metadata. - Replace later with real EXIF/PNG chunk parsing. - """ - return { - "Filename": path, - "Width": 1920, - "Height": 1080, - "Format": "PNG" - } diff --git a/image_canvas.py b/image_canvas.py index 212475d..aae8eb9 100644 --- a/image_canvas.py +++ b/image_canvas.py @@ -1,9 +1,10 @@ from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsPixmapItem from PySide6.QtGui import QPixmap, QDragEnterEvent, QDropEvent, QPainter from PySide6.QtCore import Qt, Signal -from PySide6.QtOpenGLWidgets import QOpenGLWidget # ← ADD THIS IMPORT +from PySide6.QtOpenGLWidgets import QOpenGLWidget import os +"""this defines the 'canvas' class, meaning the area where images are dropped and displayed""" class ImageCanvas(QGraphicsView): # Signal emitted when a valid file is dropped @@ -33,9 +34,21 @@ class ImageCanvas(QGraphicsView): self.setRenderHint(QPainter.Antialiasing, True) self.setRenderHint(QPainter.SmoothPixmapTransform, True) - # ← ADD OPENGL ACCELERATION HERE self.setViewport(QOpenGLWidget()) # Hardware-accelerated rendering + # Enable keyboard focus for the canvas + self.setFocusPolicy(Qt.StrongFocus) + + def keyPressEvent(self, event): + """Forward arrow keys to main window for navigation""" + if event.key() in (Qt.Key_Right, Qt.Key_Left): + main_window = self.window() # Get the actual main window, not just the immediate parent + if main_window: + main_window.keyPressEvent(event) + event.accept() + else: + super().keyPressEvent(event) + # --- Drag & Drop Events --- def dragEnterEvent(self, event: QDragEnterEvent): if event.mimeData().hasUrls(): diff --git a/mbq_layout.py b/mbq_layout.py index 3d5d8bf..2429a76 100644 --- a/mbq_layout.py +++ b/mbq_layout.py @@ -5,35 +5,36 @@ from PySide6.QtWidgets import ( ) from PySide6.QtCore import Qt from image_canvas import ImageCanvas -from image_folder import ImageFolder from PySide6.QtWidgets import QLabel -from PySide6.QtGui import QPixmap from PySide6.QtCore import QTimer -import os +from PySide6.QtCore import Qt, QTimer, QEvent + import sys -import helpers -class MetaViewApp(QMainWindow): +from metaview_logic import MetaViewLogicMixin + +class MetaViewApp(MetaViewLogicMixin, QMainWindow): + # Now inherits from both QMainWindow and our logic mixin def __init__(self): super().__init__() - self.setWindowTitle("Image Viewer Layout") - self.resize(1400, 900) - self.folder_model = None + self.setWindowTitle("Image Viewer GL Layout") - # Image cache - self.image_cache = {} # Dictionary to cache loaded images - self.cache_size = 5 # Number of images to keep cached + # --- 4:3 Optimized Window Size --- + # Calculate for 1024x768 image + UI elements + self.resize(1400, 900) # Wider window to accommodate right sidebar + + self.folder_model = None + self.image_cache = {} + self.cache_size = 5 - # --- Design reference sizes (for proportional scaling) --- - self.design_canvas_w = 672 - self.design_canvas_h = 504 - self.design_thumb_w = self.design_canvas_w // 5 # 134 - self.design_thumb_h = self.design_thumb_w * 3 // 4 # 100 - self.design_total_h = ( - self.design_canvas_h + self.design_thumb_h + 40 + 20 + 20 - ) + # --- Design reference sizes for 4:3 --- + self.design_canvas_w = 1024 # Target image width + self.design_canvas_h = 768 # Target image height + self.design_thumb_w = 120 # Thumbnail width + self.design_thumb_h = 90 # Thumbnail height (4:3) + self.scale_factor = 1.0 # ---- Central Widget ---- @@ -42,34 +43,49 @@ class MetaViewApp(QMainWindow): # ---- Master Grid Layout ---- self.main_layout = QGridLayout(central) - self.main_layout.setContentsMargins(10, 20, 30, 20) + self.main_layout.setContentsMargins(10, 20, 10, 20) self.main_layout.setSpacing(10) - # Column weights like Tkinter's columnconfigure - self.main_layout.setColumnStretch(0, 0) # left sidebar - self.main_layout.setColumnStretch(1, 5) # center area - self.main_layout.setColumnStretch(2, 3) # right panel future + # Column weights - center area for image, right for metadata + self.main_layout.setColumnStretch(0, 0) # left aesthetic spacer (fixed) + self.main_layout.setColumnStretch(1, 3) # center image area (main content) + self.main_layout.setColumnStretch(2, 1) # right metadata panel (~1/4 width) self.main_layout.setRowStretch(0, 1) # main row expands - # --- Left Sidebar --- - self.left_margin_frame = QFrame() - left_layout = QVBoxLayout(self.left_margin_frame) - left_layout.addWidget(QLabel("Sidebar")) - self.main_layout.addWidget(self.left_margin_frame, 0, 0) + # --- Left Spacer (Aesthetic) --- + self.left_spacer = QFrame() + self.left_spacer.setFixedWidth(40) # Small fixed width spacer + self.left_spacer.setStyleSheet("background: transparent;") + self.main_layout.addWidget(self.left_spacer, 0, 0) # --- Center Image Area --- - self.center_group = QGroupBox("Image View and Controls") + self.center_group = QGroupBox("Image View") + self.center_group.setStyleSheet(""" + QGroupBox { + border: 2px solid #333333; + border-radius: 4px; + margin-top: 10px; + } + QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 10px; + padding: 0 5px 0 5px; + background: palette(window); + } + """) + self.main_layout.addWidget(self.center_group, 0, 1) center_layout = QGridLayout(self.center_group) - center_layout.setRowStretch(0, 5) # image view + center_layout.setRowStretch(0, 5) # image view (most space) center_layout.setRowStretch(1, 1) # filmstrip center_layout.setRowStretch(2, 0) # buttons - center_layout.setRowStretch(3, 0) # path display later center_layout.setColumnStretch(0, 1) - # ---- Image Canvas Equivalent ---- + # ---- Image Canvas ---- self.image_view = ImageCanvas() self.image_view.fileDropped.connect(self.load_image_from_path) + self.image_view.setMinimumSize(800, 600) # 4:3 minimum center_layout.addWidget(self.image_view, 0, 0) # ---- Filmstrip Frame ---- @@ -85,11 +101,12 @@ class MetaViewApp(QMainWindow): # Thumbnail scroller self.thumb_scroll_area = QScrollArea() self.thumb_scroll_area.setWidgetResizable(True) + self.thumb_scroll_area.setMinimumHeight(100) self.thumb_container = QWidget() self.thumb_layout = QHBoxLayout(self.thumb_container) self.thumb_scroll_area.setWidget(self.thumb_container) - filmstrip_layout.addWidget(self.thumb_scroll_area) + center_layout.addWidget(self.filmstrip_frame, 1, 0) # ---- Button Frame ---- @@ -106,176 +123,56 @@ class MetaViewApp(QMainWindow): center_layout.addWidget(self.button_frame, 2, 0) - open_btn.clicked.connect(self.open_test_image) + # --- Right Metadata Panel --- + self.right_metadata = QGroupBox("Metadata") + self.right_metadata.setMinimumWidth(300) # ~1/4 of window width + metadata_layout = QVBoxLayout(self.right_metadata) + + # Placeholder metadata content + metadata_layout.addWidget(QLabel("File Information:")) + self.file_info_label = QLabel("No image loaded") + metadata_layout.addWidget(self.file_info_label) + + metadata_layout.addWidget(QLabel("AI Parameters:")) + self.ai_params_label = QLabel("Waiting for image...") + metadata_layout.addWidget(self.ai_params_label) + + metadata_layout.addStretch() # Push content to top + + self.main_layout.addWidget(self.right_metadata, 0, 2) + + # ---- Connect Signals ---- + open_btn.clicked.connect(self.open_image_file) next_btn.clicked.connect(self.show_next_image) prev_btn.clicked.connect(self.show_prev_image) - # REMOVED THE PROBLEMATIC LINE: self.resizeEvent(None) - # Instead, use a timer to initialize after UI is fully built + # Initialize after UI is built QTimer.singleShot(100, self.initialize_scale) - def initialize_scale(self): - """Initialize scale factor after UI is fully built""" - self.update_scale_factor() - if self.folder_model: - self.populate_filmstrip() - - def update_scale_factor(self): - """Calculate scale factor based on current sizes""" - if not hasattr(self, "image_view") or not hasattr(self, "filmstrip_frame"): - return + # Install event filter on THIS window only + self.installEventFilter(self) - # Current available width and height - avail_w = self.image_view.width() - avail_h = self.image_view.height() - - print(f"Available space for image: {avail_w}x{avail_h}") - - # Compute scale factors relative to design sizes - scale_w = avail_w / self.design_canvas_w - scale_h = avail_h / self.design_total_h - self.scale_factor = min(scale_w, scale_h) - print(f"Scale factor updated: {self.scale_factor}") + def eventFilter(self, obj, event): + if event.type() == QEvent.KeyPress: + print(f"🎹 EVENT FILTER: Key {event.key()} in {type(obj).__name__}") + if event.key() in (Qt.Key_Right, Qt.Key_Left): + print("🎹 EVENT FILTER: Calling keyPressEvent directly") + result = self.keyPressEvent(event) + print(f"🎹 EVENT FILTER: keyPressEvent returned {result}") + return True # Event handled, stop propagation + return super().eventFilter(obj, event) - # --- Example method using helpers --- - def open_test_image(self): - """ - Demo function: load a test image and print metadata. - """ - path = "test.png" # placeholder - try: - pixmap = helpers.load_image(path) - meta = helpers.get_fake_metadata(path) - print("Metadata:", meta) - except FileNotFoundError as e: - print(e) - - #load image with path - def load_image_from_path(self, file_path): - folder = os.path.dirname(file_path) - self.folder_model = ImageFolder(folder, start_file=file_path) - - # Clear cache when folder changes - self.image_cache.clear() - - current = self.folder_model.current() - if current: - print("Displaying:", current["name"]) - self.display_image(current["path"]) - self.populate_filmstrip() - self.preload_adjacent_images() - - # New method for displaying images - def display_image(self, path): - """Display image from cache or load it""" - if path in self.image_cache: - # Use cached pixmap - print(f"Using cached image: {os.path.basename(path)}") - self.image_view.load_image_from_pixmap(self.image_cache[path]) - else: - # Load and cache - pixmap = QPixmap(path) - if not pixmap.isNull(): - self.image_cache[path] = pixmap - self.image_view.load_image(path) - - # New method for preloading - def preload_adjacent_images(self): - """Pre-load images around current index""" - if not self.folder_model or not self.folder_model.files: - return - - files = self.folder_model.files - current_idx = self.folder_model.index - - # Pre-load 2 images on each side - for offset in range(-2, 3): - if offset == 0: - continue # Skip current (already loaded) - - idx = (current_idx + offset) % len(files) - path = files[idx]["path"] - - if path not in self.image_cache: - # Load into cache but don't display - print(f"Pre-loading: {os.path.basename(path)}") - pixmap = QPixmap(path) - if not pixmap.isNull(): - self.image_cache[path] = pixmap - - def show_next_image(self): - if self.folder_model: - current = self.folder_model.next() - if current: - self.display_image(current["path"]) - self.populate_filmstrip() - self.preload_adjacent_images() - - def show_prev_image(self): - if self.folder_model: - current = self.folder_model.prev() - if current: - self.display_image(current["path"]) - self.populate_filmstrip() - self.preload_adjacent_images() - - # Mouse wheel handler - def wheelEvent(self, event): - if event.angleDelta().y() > 0: - # wheel scrolled up - self.show_prev_image() - else: - # wheel scrolled down - self.show_next_image() - - event.accept() - - def resizeEvent(self, event): - super().resizeEvent(event) - self.update_scale_factor() - # Rebuild thumbs at new scale - if self.folder_model: - self.populate_filmstrip() - - def populate_filmstrip(self): - # Clear old thumbnails - for i in reversed(range(self.thumb_layout.count())): - item = self.thumb_layout.takeAt(i) - if widget := item.widget(): - widget.deleteLater() - - if not self.folder_model: - return - - # Scale design size by current factor - thumb_w = max(64, int(self.design_thumb_w * self.scale_factor)) - thumb_h = max(48, int(self.design_thumb_h * self.scale_factor)) - - # Show 5 thumbnails centered on current index - center_index = self.folder_model.index - files = self.folder_model.files - if not files: - return - - for offset in range(-2, 3): - idx = (center_index + offset) % len(files) - file_path = files[idx]["path"] - - pix = QPixmap(file_path).scaled( - thumb_w, thumb_h, - Qt.KeepAspectRatio, - Qt.SmoothTransformation - ) - lbl = QLabel() - lbl.setPixmap(pix) - lbl.setAlignment(Qt.AlignCenter) - - self.thumb_layout.addWidget(lbl) + def check_focus(self): + """Check what has focus""" + print(f"🎯 Current focus widget: {self.focusWidget()}") + print(f"🎯 Main window has focus: {self.hasFocus()}") + print(f"🎯 Image view has focus: {self.image_view.hasFocus()}") if __name__ == "__main__": app = QApplication(sys.argv) window = MetaViewApp() window.show() sys.exit(app.exec()) + diff --git a/xx.py b/metaview_logic.py similarity index 50% rename from xx.py rename to metaview_logic.py index 245e412..3404bca 100644 --- a/xx.py +++ b/metaview_logic.py @@ -1,169 +1,55 @@ -from PySide6.QtWidgets import ( - QApplication, QMainWindow, QWidget, QFrame, QGroupBox, - QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QPushButton, - QScrollArea -) + + +# metaview_logic.py from PySide6.QtCore import Qt -from image_canvas import ImageCanvas from image_folder import ImageFolder from PySide6.QtWidgets import QLabel from PySide6.QtGui import QPixmap -from PySide6.QtCore import QTimer from PySide6.QtGui import QPainter -from ui_styles import create_styled_groupbox +from PySide6.QtWidgets import QFileDialog +from pathlib import Path + +import struct +import zlib import os -import sys -import helpers +class MetaViewLogicMixin: + """All the behavior logic goes here - no UI creation""" + # Mouse wheel handler + def wheelEvent(self, event): + if event.angleDelta().y() > 0: + # wheel scrolled up + self.show_prev_image() + else: + # wheel scrolled down + self.show_next_image() -class MetaViewApp(QMainWindow): - def __init__(self): - super().__init__() - self.setWindowTitle("Image Viewer GL Layout") - - # --- 4:3 Optimized Window Size --- - # Calculate for 1024x768 image + UI elements - self.resize(1400, 900) # Wider window to accommodate right sidebar - - self.folder_model = None - self.image_cache = {} - self.cache_size = 5 - - # --- Design reference sizes for 4:3 --- - self.design_canvas_w = 1024 # Target image width - self.design_canvas_h = 768 # Target image height - self.design_thumb_w = 120 # Thumbnail width - self.design_thumb_h = 90 # Thumbnail height (4:3) - - self.scale_factor = 1.0 - - # ---- Central Widget ---- - central = QWidget() - self.setCentralWidget(central) - - # ---- Master Grid Layout ---- - self.main_layout = QGridLayout(central) - self.main_layout.setContentsMargins(10, 20, 10, 20) - self.main_layout.setSpacing(10) - - # Column weights - center area for image, right for metadata - self.main_layout.setColumnStretch(0, 0) # left aesthetic spacer (fixed) - self.main_layout.setColumnStretch(1, 3) # center image area (main content) - self.main_layout.setColumnStretch(2, 1) # right metadata panel (~1/4 width) - self.main_layout.setRowStretch(0, 1) # main row expands - - # --- Left Spacer (Aesthetic) --- - self.left_spacer = QFrame() - self.left_spacer.setFixedWidth(40) # Small fixed width spacer - self.left_spacer.setStyleSheet("background: transparent;") - self.main_layout.addWidget(self.left_spacer, 0, 0) - - # --- Center Image Area --- - self.center_group = QGroupBox("Image View") - # Keep everything default Qt style, just make borders darker - #self.center_group.setStyleSheet("QGroupBox { border: 2px solid red; }") - self.center_group.setStyleSheet(""" - QGroupBox { - border: 2px solid #333333; - border-radius: 4px; - margin-top: 10px; - } - QGroupBox::title { - subcontrol-origin: margin; - subcontrol-position: top left; - left: 10px; - padding: 0 5px 0 5px; - background: palette(window); - } - """) -#self.right_metadata.setStyleSheet("QGroupBox { border-color: #222222; }") - self.main_layout.addWidget(self.center_group, 0, 1) - center_layout = QGridLayout(self.center_group) - center_layout.setRowStretch(0, 5) # image view (most space) - center_layout.setRowStretch(1, 1) # filmstrip - center_layout.setRowStretch(2, 0) # buttons - center_layout.setColumnStretch(0, 1) - - # ---- Image Canvas ---- - self.image_view = ImageCanvas() - self.image_view.fileDropped.connect(self.load_image_from_path) - self.image_view.setMinimumSize(800, 600) # 4:3 minimum - center_layout.addWidget(self.image_view, 0, 0) - - # ---- Filmstrip Frame ---- - self.filmstrip_frame = QFrame() - filmstrip_layout = QVBoxLayout(self.filmstrip_frame) - - # Top separator - sep = QFrame() - sep.setFrameShape(QFrame.HLine) - sep.setStyleSheet("color: #252222;") - filmstrip_layout.addWidget(sep) - - # Thumbnail scroller - self.thumb_scroll_area = QScrollArea() - self.thumb_scroll_area.setWidgetResizable(True) - self.thumb_scroll_area.setMinimumHeight(100) - self.thumb_container = QWidget() - self.thumb_layout = QHBoxLayout(self.thumb_container) - self.thumb_scroll_area.setWidget(self.thumb_container) - filmstrip_layout.addWidget(self.thumb_scroll_area) - - center_layout.addWidget(self.filmstrip_frame, 1, 0) - - # ---- Button Frame ---- - self.button_frame = QFrame() - btn_layout = QHBoxLayout(self.button_frame) - - next_btn = QPushButton("Next Image") - prev_btn = QPushButton("Previous Image") - open_btn = QPushButton("Open Image") - - btn_layout.addWidget(next_btn) - btn_layout.addWidget(prev_btn) - btn_layout.addWidget(open_btn) - - center_layout.addWidget(self.button_frame, 2, 0) - - # --- Right Metadata Panel --- - self.right_metadata = QGroupBox("Metadata") - self.right_metadata.setMinimumWidth(300) # ~1/4 of window width - metadata_layout = QVBoxLayout(self.right_metadata) - - # Placeholder metadata content - metadata_layout.addWidget(QLabel("File Information:")) - self.file_info_label = QLabel("No image loaded") - metadata_layout.addWidget(self.file_info_label) - - metadata_layout.addWidget(QLabel("AI Parameters:")) - self.ai_params_label = QLabel("Waiting for image...") - metadata_layout.addWidget(self.ai_params_label) - - metadata_layout.addStretch() # Push content to top - - self.main_layout.addWidget(self.right_metadata, 0, 2) - - # ---- Connect Signals ---- - open_btn.clicked.connect(self.open_test_image) - next_btn.clicked.connect(self.show_next_image) - prev_btn.clicked.connect(self.show_prev_image) - - # Initialize after UI is built - QTimer.singleShot(100, self.initialize_scale) + event.accept() + return super().wheelEvent(event) # ← FIXED: Only call super() once + # arrow / key nav + def keyPressEvent(self, event): + if event.key() == Qt.Key_Right: + self.show_next_image() + event.accept() + elif event.key() == Qt.Key_Left: + self.show_prev_image() + event.accept() + else: + super().keyPressEvent(event) + def initialize_scale(self): """Initialize after UI is fully built""" self.update_scale_factor() if self.folder_model: self.populate_filmstrip() - + def update_scale_factor(self): """Calculate scale factor based on current image view size""" if not hasattr(self, "image_view"): return - # Use only the image view's available space avail_w = self.image_view.width() avail_h = self.image_view.height() @@ -172,20 +58,15 @@ class MetaViewApp(QMainWindow): scale_h = avail_h / self.design_canvas_h self.scale_factor = min(scale_w, scale_h) - # --- Image Handling --- - def load_image_from_path(self, file_path): - folder = os.path.dirname(file_path) - self.folder_model = ImageFolder(folder, start_file=file_path) - self.image_cache.clear() - - current = self.folder_model.current() - if current: - print("Displaying:", current["name"]) - self.display_image(current["path"]) - self.update_metadata(current) # Update metadata panel - self.populate_filmstrip() - self.preload_adjacent_images() + + def resizeEvent(self, event): + super().resizeEvent(event) + self.update_scale_factor() + if self.folder_model: + self.populate_filmstrip() + + #kind of a placeholder here for png chunks later def update_metadata(self, file_info): """Update the right metadata panel with file information""" self.file_info_label.setText( @@ -202,15 +83,18 @@ class MetaViewApp(QMainWindow): "CFG: 7.5" ) - def display_image(self, path): - """Display image from cache or load it""" - if path in self.image_cache: - self.image_view.load_image_from_pixmap(self.image_cache[path]) - else: - pixmap = QPixmap(path) - if not pixmap.isNull(): - self.image_cache[path] = pixmap - self.image_view.load_image(path) + def load_image_from_path(self, file_path): + folder = os.path.dirname(file_path) + self.folder_model = ImageFolder(folder, start_file=file_path) + self.image_cache.clear() + + current = self.folder_model.current() + if current: + print("Displaying:", current["name"]) + self.display_image(current["path"]) + self.update_metadata(current) # Update metadata panel + self.populate_filmstrip() + self.preload_adjacent_images() def preload_adjacent_images(self): """Pre-load images around current index""" @@ -230,6 +114,16 @@ class MetaViewApp(QMainWindow): if not pixmap.isNull(): self.image_cache[path] = pixmap + def display_image(self, path): + """Display image from cache or load it""" + if path in self.image_cache: + self.image_view.load_image_from_pixmap(self.image_cache[path]) + else: + pixmap = QPixmap(path) + if not pixmap.isNull(): + self.image_cache[path] = pixmap + self.image_view.load_image(path) + def show_next_image(self): if self.folder_model: current = self.folder_model.next() @@ -247,20 +141,8 @@ class MetaViewApp(QMainWindow): self.update_metadata(current) self.populate_filmstrip() self.preload_adjacent_images() - - def wheelEvent(self, event): - if event.angleDelta().y() > 0: - self.show_prev_image() - else: - self.show_next_image() - event.accept() - - def resizeEvent(self, event): - super().resizeEvent(event) - self.update_scale_factor() - if self.folder_model: - self.populate_filmstrip() - + + def populate_filmstrip(self): # Clear old thumbnails for i in reversed(range(self.thumb_layout.count())): @@ -324,18 +206,24 @@ class MetaViewApp(QMainWindow): self.thumb_layout.addWidget(lbl) - def open_test_image(self): - path = "test.png" - try: - pixmap = helpers.load_image(path) - meta = helpers.get_fake_metadata(path) - print("Metadata:", meta) - except FileNotFoundError as e: - print(e) + from PySide6.QtWidgets import QFileDialog + + def open_image_file(self): + """Open file dialog to select an image""" + file_dialog = QFileDialog(self) + file_dialog.setWindowTitle("Open Image File") + file_dialog.setNameFilter("Images (*.png *.jpg *.jpeg *.bmp *.gif *.tiff *.webp)") + file_dialog.setFileMode(QFileDialog.ExistingFile) + + if file_dialog.exec(): + selected_files = file_dialog.selectedFiles() + if selected_files: + file_path = selected_files[0] + self.load_image_from_path(file_path) + + + + + -if __name__ == "__main__": - app = QApplication(sys.argv) - window = MetaViewApp() - window.show() - sys.exit(app.exec())