Explorar el Código

Preview images on file dialogs (#948)

* Preview images on file dialogs

* flake8

* Refactoring

* Refactoring

Co-authored-by: Kentaro Wada <www.kentaro.wada@gmail.com>
Bc. Martin Kubovčík hace 3 años
padre
commit
8515fd6f4a
Se han modificado 3 ficheros con 90 adiciones y 12 borrados
  1. 11 12
      labelme/app.py
  2. 2 0
      labelme/widgets/__init__.py
  3. 77 0
      labelme/widgets/file_dialog_preview.py

+ 11 - 12
labelme/app.py

@@ -15,7 +15,6 @@ from qtpy import QtWidgets
 
 from labelme import __appname__
 from labelme import PY2
-from labelme import QT5
 
 from . import utils
 from labelme.config import get_config
@@ -25,6 +24,7 @@ from labelme.logger import logger
 from labelme.shape import Shape
 from labelme.widgets import BrightnessContrastDialog
 from labelme.widgets import Canvas
+from labelme.widgets import FileDialogPreview
 from labelme.widgets import LabelDialog
 from labelme.widgets import LabelListWidget
 from labelme.widgets import LabelListWidgetItem
@@ -32,12 +32,10 @@ from labelme.widgets import ToolBar
 from labelme.widgets import UniqueLabelQListWidget
 from labelme.widgets import ZoomWidget
 
-
 # FIXME
 # - [medium] Set max zoom value to something big enough for FitWidth/Window
 
 # TODO(unknown):
-# - [low,maybe] Preview images on file dialogs.
 # - Zoom is too "steppy".
 
 
@@ -1746,17 +1744,18 @@ class MainWindow(QtWidgets.QMainWindow):
         filters = self.tr("Image & Label files (%s)") % " ".join(
             formats + ["*%s" % LabelFile.suffix]
         )
-        filename = QtWidgets.QFileDialog.getOpenFileName(
-            self,
+        fileDialog = FileDialogPreview(self)
+        fileDialog.setFileMode(FileDialogPreview.ExistingFile)
+        fileDialog.setNameFilter(filters)
+        fileDialog.setWindowTitle(
             self.tr("%s - Choose Image or Label file") % __appname__,
-            path,
-            filters,
         )
-        if QT5:
-            filename, _ = filename
-        filename = str(filename)
-        if filename:
-            self.loadFile(filename)
+        fileDialog.setWindowFilePath(path)
+        fileDialog.setViewMode(FileDialogPreview.Detail)
+        if fileDialog.exec_():
+            fileName = fileDialog.selectedFiles()[0]
+            if fileName:
+                self.loadFile(fileName)
 
     def changeOutputDirDialog(self, _value=False):
         default_output_dir = self.output_dir

+ 2 - 0
labelme/widgets/__init__.py

@@ -6,6 +6,8 @@ from .canvas import Canvas
 
 from .color_dialog import ColorDialog
 
+from .file_dialog_preview import FileDialogPreview
+
 from .label_dialog import LabelDialog
 from .label_dialog import LabelQLineEdit
 

+ 77 - 0
labelme/widgets/file_dialog_preview.py

@@ -0,0 +1,77 @@
+from qtpy import QtCore
+from qtpy import QtGui
+from qtpy import QtWidgets
+
+import json
+
+
+class ScrollAreaPreview(QtWidgets.QScrollArea):
+    def __init__(self, *args, **kwargs):
+        super(ScrollAreaPreview, self).__init__(*args, **kwargs)
+
+        self.setWidgetResizable(True)
+
+        content = QtWidgets.QWidget(self)
+        self.setWidget(content)
+
+        lay = QtWidgets.QVBoxLayout(content)
+
+        self.label = QtWidgets.QLabel(content)
+        self.label.setWordWrap(True)
+
+        lay.addWidget(self.label)
+
+    def setText(self, text):
+        self.label.setText(text)
+
+    def setPixmap(self, pixmap):
+        self.label.setPixmap(pixmap)
+
+    def clear(self):
+        self.label.clear()
+
+
+class FileDialogPreview(QtWidgets.QFileDialog):
+    def __init__(self, *args, **kwargs):
+        super(FileDialogPreview, self).__init__(*args, **kwargs)
+        self.setOption(self.DontUseNativeDialog, True)
+
+        self.labelPreview = ScrollAreaPreview(self)
+        self.labelPreview.setFixedSize(300, 300)
+        self.labelPreview.setHidden(True)
+
+        box = QtWidgets.QVBoxLayout()
+        box.addWidget(self.labelPreview)
+        box.addStretch()
+
+        self.setFixedSize(self.width() + 300, self.height())
+        self.layout().addLayout(box, 1, 3, 1, 1)
+        self.currentChanged.connect(self.onChange)
+
+    def onChange(self, path):
+        if path.lower().endswith(".json"):
+            with open(path, "r") as f:
+                data = json.load(f)
+                self.labelPreview.setText(
+                    json.dumps(data, indent=4, sort_keys=False)
+                )
+            self.labelPreview.label.setAlignment(
+                QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop
+            )
+            self.labelPreview.setHidden(False)
+        else:
+            pixmap = QtGui.QPixmap(path)
+            if pixmap.isNull():
+                self.labelPreview.clear()
+                self.labelPreview.setHidden(True)
+            else:
+                self.labelPreview.setPixmap(
+                    pixmap.scaled(
+                        self.labelPreview.width() - 30,
+                        self.labelPreview.height() - 30,
+                        QtCore.Qt.KeepAspectRatio,
+                        QtCore.Qt.SmoothTransformation,
+                    )
+                )
+                self.labelPreview.label.setAlignment(QtCore.Qt.AlignCenter)
+                self.labelPreview.setHidden(False)