From 238afcd4d6e63b2f4cf8277f5c6e5661ba44d6c0 Mon Sep 17 00:00:00 2001 From: CodeByMrFinchum Date: Wed, 8 Jan 2025 15:46:41 +0100 Subject: [PATCH] Added preview window. --- src/OptimaLab35/__init__.py | 2 +- src/OptimaLab35/gui.py | 183 ++++++++++++++++++++++++++++++++---- 2 files changed, 167 insertions(+), 18 deletions(-) diff --git a/src/OptimaLab35/__init__.py b/src/OptimaLab35/__init__.py index 485f44a..443d478 100644 --- a/src/OptimaLab35/__init__.py +++ b/src/OptimaLab35/__init__.py @@ -1 +1 @@ -__version__ = "0.1.1" +__version__ = "0.2.0-a1" diff --git a/src/OptimaLab35/gui.py b/src/OptimaLab35/gui.py index 19294fd..10421cf 100644 --- a/src/OptimaLab35/gui.py +++ b/src/OptimaLab35/gui.py @@ -2,13 +2,19 @@ import sys import os from datetime import datetime +import time + from optima35.core import OptimaManager from OptimaLab35.utils.utility import Utilities from OptimaLab35.ui.main_window import Ui_MainWindow +#from OptimaLab35.ui.test_window import Ui_Test_Window +from OptimaLab35.ui.preview_window import Ui_Preview_Window from OptimaLab35.ui.exif_handler_window import ExifEditor from OptimaLab35.ui.simple_dialog import SimpleDialog # Import the SimpleDialog class from OptimaLab35 import __version__ +from PySide6.QtCore import Signal + from PySide6 import QtWidgets from PySide6.QtWidgets import ( QMessageBox, @@ -23,8 +29,68 @@ from PySide6.QtWidgets import ( QFileDialog, QHBoxLayout, QSpinBox, + QProgressBar, ) +from PySide6.QtGui import QPixmap + +class PreviewWindow(QMainWindow, Ui_Preview_Window): + values_selected = Signal(int, int, bool) + + def __init__(self): + super(PreviewWindow, self).__init__() + self.ui = Ui_Preview_Window() + self.ui.setupUi(self) + self.o = OptimaManager() + ## Ui interaction + self.ui.load_Button.clicked.connect(self._browse_file) + self.ui.update_Button.clicked.connect(self._update_preview) + self.ui.close_Button.clicked.connect(self._close_window) + + self.ui.reset_brightness_Button.clicked.connect(lambda: self.ui.brightness_spinBox.setValue(0)) + self.ui.reset_contrast_Button.clicked.connect(lambda: self.ui.contrast_spinBox.setValue(0)) + self.preview_image = None + + def _browse_file(self): + file = QFileDialog.getOpenFileName(self, caption = "Select File", filter = ("Images (*.png *.webp *.jpg *.jpeg)")) + if file[0]: + self.ui.image_path_lineEdit.setText(file[0]) + self._update_preview() + + def _supdate_preview(self): + self._update_preview() + pass + + def _update_preview(self): + path = self.ui.image_path_lineEdit.text() + if not os.path.isfile(path): + return + try: + img = self.o.process_image( + save = False, + image_input_file = path, + image_output_file = "", + quality = 50, + optimize = True, + grayscale = self.ui.grayscale_checkBox.isChecked(), + brightness = int(self.ui.brightness_spinBox.text()), + contrast = int(self.ui.contrast_spinBox.text()), + ) + except Exception: + QMessageBox.warning(self, "Warning", "Error loading image...") + print("Error loading image...") + return + # Create a QPixmap object from an image file + + self.preview_image = QPixmap.fromImage(img) + self.ui.QLabel.setPixmap(self.preview_image) + + def _close_window(self): + # Emit the signal with the values from the spinboxes and checkbox + if self.ui.checkBox.isChecked(): + self.values_selected.emit(self.ui.brightness_spinBox.value(), self.ui.contrast_spinBox.value(), self.ui.grayscale_checkBox.isChecked()) + self.close() + class OptimaLab35(QMainWindow, Ui_MainWindow): def __init__(self): super(OptimaLab35, self).__init__() @@ -44,14 +110,30 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): self.sd = SimpleDialog() self._change_statusbar(f"Using {self.o.name} v{self.o.version}", 5000) + # Instantiate the second window + self.preview_window = PreviewWindow() + + # Connect button to open the second window + + def open_preview_window(self): + self.preview_window.values_selected.connect(self.update_values) + self.preview_window.show() + + def update_values(self, value1, value2, checkbox_state): + # Update main window's widgets with the received values + self.ui.brightness_spinBox.setValue(value1) + self.ui.contrast_spinBox.setValue(value2) + self.ui.grayscale_checkBox.setChecked(checkbox_state) def _default_ui_layout(self): self.ui.png_quality_spinBox.setVisible(False) + self.ui.png_quality_Slider.setVisible(False) + self.ui.quality_label_2.setVisible(False) def _define_gui_interaction(self): self.ui.input_folder_button.clicked.connect(self._browse_input_folder) self.ui.output_folder_button.clicked.connect(self._browse_output_folder) - self.ui.start_button.clicked.connect(self._process) + self.ui.start_button.clicked.connect(self._start_process) self.ui.image_type.currentIndexChanged.connect(self._update_quality_options) self.ui.exif_checkbox.stateChanged.connect( @@ -60,7 +142,18 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): self.ui.tabWidget.currentChanged.connect(self._on_tab_changed) self.ui.edit_exif_button.clicked.connect(self._open_exif_editor) - self.ui.actionInfo.triggered.connect(self._info_window) + self.ui.actionAbout.triggered.connect(self._info_window) + self.ui.actionPreview.triggered.connect(self.open_preview_window) + self.ui.preview_Button.clicked.connect(self.open_preview_window) + + def _debug(self): + for i in range(10): + print(f"Testing... {i}") + time.sleep(.3) + + self._handle_qprogressbar(i, 10) + print("Finished") + self.ui.progressBar.setValue(0) def _info_window(self): info_text = f""" @@ -75,21 +168,62 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): self.sd.show_dialog(f"{self.name} v{self.version}", info_text) - def _process(self): - self.ui.start_button.setEnabled(False) + def _prepear_image(self): + pass + + def _image_list_from_folder(self, path): + image_files = [ + f for f in os.listdir(path) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")) + ] + return image_files + + def _start_process(self): + self._toggle_buttons(False) self._update_settings() # Get all user selected data - input_folder_valid = os.path.exists(self.settings["input_folder"]) - output_folder_valid = os.path.exists(self.settings["output_folder"]) - if not input_folder_valid or not output_folder_valid: - QMessageBox.warning(self, "Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...") + input_folder = self.settings["input_folder"] + output_folder = self.settings["output_folder"] + if not input_folder or not output_folder: + QMessageBox.warning(self, "Warning", "Input or output folder not selected") + self._toggle_buttons(True) return + input_folder_valid = os.path.exists(input_folder) + output_folder_valid = os.path.exists(output_folder) + if not input_folder_valid or not output_folder_valid: + QMessageBox.warning(self, "Warning", f"Input location {input_folder_valid}\nOutput folder {output_folder_valid}...") + self._toggle_buttons(True) + return + + image_list = self._image_list_from_folder(input_folder) + if len(image_list) == 0: + QMessageBox.warning(self, "Warning", "Selected folder has no supported files.") + self._toggle_buttons(True) + return + + if len(self._image_list_from_folder(output_folder)) != 0: + reply = QMessageBox.question( + self, + "Confirmation", + "Output folder containes images, which might get overritten, continue?", + QMessageBox.Yes | QMessageBox.No, + ) + + if reply == QMessageBox.No: + self._toggle_buttons(True) + return + + self._process_images(image_list) + + self._toggle_buttons(True) + QMessageBox.information(self, "Information", "Finished") + + def _toggle_buttons(self, state): + self.ui.start_button.setEnabled(state) + + def _process_images(self, image_files): input_folder = self.settings["input_folder"] output_folder = self.settings["output_folder"] - image_files = [ - f for f in os.listdir(input_folder) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")) - ] i = 1 for image_file in image_files: input_path = os.path.join(input_folder, image_file) @@ -118,8 +252,6 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): self._handle_qprogressbar(i, len(image_files)) i += 1 - QMessageBox.information(self, "Information", "Finished") - self.ui.start_button.setEnabled(True) self.ui.progressBar.setValue(0) def _open_exif_editor(self): @@ -181,13 +313,23 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): # Hide all quality settings self.ui.png_quality_spinBox.setVisible(False) self.ui.jpg_quality_spinBox.setVisible(False) + self.ui.jpg_quality_Slider.setVisible(False) + self.ui.png_quality_Slider.setVisible(False) + self.ui.quality_label_1.setVisible(False) + self.ui.quality_label_2.setVisible(False) # Show relevant settings if selected_format == "jpg": self.ui.jpg_quality_spinBox.setVisible(True) + self.ui.jpg_quality_Slider.setVisible(True) + self.ui.quality_label_1.setVisible(True) elif selected_format == "webp": self.ui.jpg_quality_spinBox.setVisible(True) + self.ui.jpg_quality_Slider.setVisible(True) + self.ui.quality_label_1.setVisible(True) elif selected_format == "png": self.ui.png_quality_spinBox.setVisible(True) + self.ui.png_quality_Slider.setVisible(True) + self.ui.quality_label_2.setVisible(True) def _browse_input_folder(self): folder = QFileDialog.getExistingDirectory(self, "Select Input Folder") @@ -251,12 +393,16 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): self.settings["own_date"] = self._get_checkbox_value(self.ui.add_date_checkBox) # Conditional settings with logic - self.settings["resize"] = self._get_spinbox_value(self.ui.resize_spinBox) if self.ui.resize_checkbox.isChecked() else None - self.settings["brightness"] = self._get_spinbox_value(self.ui.brightness_spinBox) if self.ui.brightness_checkbox.isChecked() else None - self.settings["contrast"] = self._get_spinbox_value(self.ui.contrast_spinBox) if self.ui.contrast_checkbox.isChecked() else None + self.settings["resize"] = int(self.ui.resize_spinBox.text()) if self.ui.resize_spinBox.text() != "100" else None + #self._get_spinbox_value(self.ui.resize_spinBox) if self.ui.resize_checkbox.isChecked() else None + self.settings["brightness"] = int(self.ui.brightness_spinBox.text()) if self.ui.brightness_spinBox.text() != "0" else None + #self._get_spinbox_value(self.ui.brightness_spinBox) if self.ui.brightness_checkbox.isChecked() else None + self.settings["contrast"] = int(self.ui.contrast_spinBox.text()) if self.ui.contrast_spinBox.text() != "0" else None + #self._get_spinbox_value(self.ui.contrast_spinBox) if self.ui.contrast_checkbox.isChecked() else None self.settings["new_file_names"] = self._get_text_value(self.ui.filename, False) if self.ui.rename_checkbox.isChecked() else False - self.settings["watermark"] = self._get_text_value(self.ui.watermark_lineEdit) if self.ui.watermark_checkbox.isChecked() else None + self.settings["watermark"] = self.ui.watermark_lineEdit.text() if len(self.ui.watermark_lineEdit.text()) != 0 else None + #self._get_text_value(self.ui.watermark_lineEdit) if self.ui.watermark_checkbox.isChecked() else None # Handle EXIF data selection if self.settings["own_exif"]: @@ -283,6 +429,9 @@ class OptimaLab35(QMainWindow, Ui_MainWindow): user_data["software"] = f"{self.o.name} {self.o.version}" return user_data + def closeEvent(self, event): + self.preview_window.close() + def main(): app = QtWidgets.QApplication(sys.argv) window = OptimaLab35()