From 4de9ea68dfbea7d6d8aa9dc5ea0c4b6328e55dc1 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 30 Oct 2026 19:22:01 +0100 Subject: Add Clear action to empty the view Deletes the job's temp PNGs, which reach hundreds of MB at 4x. Asks before discarding an upscaled result that was neither saved nor written over the original. Co-Authored-By: Claude Opus 5.5 --- README.md | 1 + test_upscale_qt.py | 5 +++++ upscale-qt | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/README.md b/README.md index bc59a39..cd73c5e 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Small PyQt6 app to upscale an image with an ESRGAN model through `sd-cli` (stabl - Pick a model and Upscale (Ctrl+U). Expect roughly 25 seconds per megapixel of input; the result is 4x in each direction. - The view shows before left of the divider and after right of it. Drag the divider to wipe, drag elsewhere to pan, mouse wheel to zoom, double-click to fit. - Save As (Ctrl+Shift+S) writes a new file. Overwrite replaces the original after a confirmation, in the same format. EXIF metadata is not kept. +- Clear (Ctrl+W) empties the view and deletes the temp files. It asks first if the upscaled image was not saved. - Settings holds the upscalers folder. ### Model descriptions diff --git a/test_upscale_qt.py b/test_upscale_qt.py index cb11346..66423e8 100644 --- a/test_upscale_qt.py +++ b/test_upscale_qt.py @@ -107,6 +107,11 @@ def test_main_window(): assert w.a_up.isEnabled() and not w.a_save.isEnabled() assert w.models.itemText(0) == 'Clean photos: people, nature [a]' assert w.models.currentData() == 'a.pth' + assert w.a_clear.isEnabled() + temp_in = w.jobs[0].input + w.clear() + assert w.jobs == [] and w.view.before is None and not os.path.exists(temp_in) + assert not w.a_clear.isEnabled() and not w.a_up.isEnabled() if __name__ == '__main__': diff --git a/upscale-qt b/upscale-qt index 7bd9964..b9a3bdd 100755 --- a/upscale-qt +++ b/upscale-qt @@ -90,6 +90,7 @@ class Job: model: str = '' out: str = '' result: QImage | None = None + saved: bool = False class CompareView(QWidget): @@ -242,6 +243,7 @@ class Main(QMainWindow): self.a_up = act('Upscale', self.upscale, 'Ctrl+U') self.a_save = act('Save As', self.save_as, QKeySequence.StandardKey.SaveAs) self.a_over = act('Overwrite', self.overwrite) + self.a_clear = act('Clear', self.clear, 'Ctrl+W') act('Settings', self.settings) self.proc = QProcess(self) @@ -284,6 +286,7 @@ class Main(QMainWindow): f'No models in {self.get("upscalers_dir")}, see Settings') self.a_save.setEnabled(done and not busy) self.a_over.setEnabled(done and not busy) + self.a_clear.setEnabled(job is not None and not busy) def open_dialog(self): path, _ = QFileDialog.getOpenFileName( @@ -368,6 +371,7 @@ class Main(QMainWindow): if not path: return if job.result.save(path, None, JPEG_QUALITY): + job.saved = True self.statusBar().showMessage(f'Saved {path}') else: QMessageBox.warning(self, 'upscale-qt', f'Cannot save {path}') @@ -381,10 +385,26 @@ class Main(QMainWindow): 'This cannot be undone.') != QMessageBox.StandardButton.Yes: return if save_over(r, job.path): + job.saved = True self.statusBar().showMessage(f'Overwrote {job.path}') else: QMessageBox.warning(self, 'upscale-qt', f'Cannot write {job.path}, original untouched') + def clear(self): + job = self.job() + if job.result is not None and not job.saved and QMessageBox.question( + self, 'Clear', 'The upscaled image is not saved. Discard it?' + ) != QMessageBox.StandardButton.Yes: + return + for f in (job.input, job.out): + if f and os.path.exists(f): + os.remove(f) # 4x PNGs run to hundreds of MB + self.jobs, self.cur = [], None + self.view.set_images(None) + self.setWindowTitle('upscale-qt') + self.statusBar().clearMessage() + self.refresh() + def settings(self): if SettingsDialog(self, self.cfg).exec(): self.reload_models() -- cgit v1.2.3