diff --git a/res/designer/imagestackwidget.ui b/res/designer/imagestackwidget.ui new file mode 100644 index 0000000..524a58a --- /dev/null +++ b/res/designer/imagestackwidget.ui @@ -0,0 +1,79 @@ + + + ImageStackWidget + + + + 0 + 0 + 400 + 112 + + + + + 16777215 + 112 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Image + + + + + + Dimensions: + + + + + + + AxBxC px + + + + + + + Override pre-dertermined scaling + + + + + + + + + + Scaling: + + + + + + + + + + + diff --git a/src/cmlibs/widgets/imagestackwidget.py b/src/cmlibs/widgets/imagestackwidget.py new file mode 100644 index 0000000..0bd28e3 --- /dev/null +++ b/src/cmlibs/widgets/imagestackwidget.py @@ -0,0 +1,59 @@ + +from PySide6 import QtCore, QtGui, QtWidgets + +from cmlibs.widgets.ui.ui_imagestackwidget import Ui_ImageStackWidget + + +INVALID_STYLE_SHEET = 'background-color: rgba(239, 0, 0, 50)' +DEFAULT_STYLE_SHEET = '' + + +class ImageStackWidget(QtWidgets.QWidget): + + scale_updated = QtCore.Signal(list) + + def __init__(self, dimensions, parent=None): + QtWidgets.QWidget.__init__(self, parent) + self._ui = Ui_ImageStackWidget() + self._ui.setupUi(self) + + self._number_of_dimensions = len(dimensions) + display_dimensions = ", ".join([f"{d}" for d in dimensions]) + self._ui.imagePixelOutputLabel.setText(f"{display_dimensions} px") + + self._set_scale_validator() + self._make_connections() + + def _set_scale_validator(self): + regex = QtCore.QRegularExpression(f"^[0-9.]+(, ?[0-9.]+){{{self._number_of_dimensions - 1}}}$") + validator = QtGui.QRegularExpressionValidator(regex) + self._ui.scalingLineEdit.setValidator(validator) + + def _make_connections(self): + self._ui.scalingLineEdit.editingFinished.connect(self.update_scale) + self._ui.scalingLineEdit.textChanged.connect(self._update_style_sheets) + + def _update_style_sheets(self): + if not self._ui.scalingLineEdit.hasAcceptableInput(): + self._ui.scalingLineEdit.setStyleSheet(INVALID_STYLE_SHEET) + else: + self._ui.scalingLineEdit.setStyleSheet(DEFAULT_STYLE_SHEET) + + def update_scale(self): + self._ui.scalingLineEdit.setStyleSheet(DEFAULT_STYLE_SHEET) + + text = self._ui.scalingLineEdit.text() + scale = [float(x.strip()) for x in text.split(',')] + self.scale_updated.emit(scale) + + def get_scaling(self): + return self._ui.scalingLineEdit.text() + + def set_scaling(self, scaling): + self._ui.scalingLineEdit.setText(scaling) + + def scaling_overridden(self): + return self._ui.overrideScalingCheckBox.isChecked() + + def override_scaling(self, override): + self._ui.overrideScalingCheckBox.setChecked(override) diff --git a/src/cmlibs/widgets/ui/ui_imagestackwidget.py b/src/cmlibs/widgets/ui/ui_imagestackwidget.py new file mode 100644 index 0000000..274f819 --- /dev/null +++ b/src/cmlibs/widgets/ui/ui_imagestackwidget.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'imagestackwidget.ui' +## +## Created by: Qt User Interface Compiler version 6.5.1 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QCheckBox, QFormLayout, QGroupBox, + QLabel, QLineEdit, QSizePolicy, QVBoxLayout, + QWidget) + +class Ui_ImageStackWidget(object): + def setupUi(self, ImageStackWidget): + if not ImageStackWidget.objectName(): + ImageStackWidget.setObjectName(u"ImageStackWidget") + ImageStackWidget.resize(400, 112) + ImageStackWidget.setMaximumSize(QSize(16777215, 112)) + self.verticalLayout = QVBoxLayout(ImageStackWidget) + self.verticalLayout.setObjectName(u"verticalLayout") + self.verticalLayout.setContentsMargins(0, 0, 0, 0) + self.groupBoxImage = QGroupBox(ImageStackWidget) + self.groupBoxImage.setObjectName(u"groupBoxImage") + self.formLayout_2 = QFormLayout(self.groupBoxImage) + self.formLayout_2.setObjectName(u"formLayout_2") + self.label_1 = QLabel(self.groupBoxImage) + self.label_1.setObjectName(u"label_1") + + self.formLayout_2.setWidget(0, QFormLayout.LabelRole, self.label_1) + + self.imagePixelOutputLabel = QLabel(self.groupBoxImage) + self.imagePixelOutputLabel.setObjectName(u"imagePixelOutputLabel") + + self.formLayout_2.setWidget(0, QFormLayout.FieldRole, self.imagePixelOutputLabel) + + self.overrideScalingCheckBox = QCheckBox(self.groupBoxImage) + self.overrideScalingCheckBox.setObjectName(u"overrideScalingCheckBox") + + self.formLayout_2.setWidget(2, QFormLayout.FieldRole, self.overrideScalingCheckBox) + + self.scalingLineEdit = QLineEdit(self.groupBoxImage) + self.scalingLineEdit.setObjectName(u"scalingLineEdit") + + self.formLayout_2.setWidget(3, QFormLayout.FieldRole, self.scalingLineEdit) + + self.label_2 = QLabel(self.groupBoxImage) + self.label_2.setObjectName(u"label_2") + + self.formLayout_2.setWidget(3, QFormLayout.LabelRole, self.label_2) + + + self.verticalLayout.addWidget(self.groupBoxImage) + + + self.retranslateUi(ImageStackWidget) + + QMetaObject.connectSlotsByName(ImageStackWidget) + # setupUi + + def retranslateUi(self, ImageStackWidget): + ImageStackWidget.setWindowTitle(QCoreApplication.translate("ImageStackWidget", u"Form", None)) + self.groupBoxImage.setTitle(QCoreApplication.translate("ImageStackWidget", u"Image", None)) + self.label_1.setText(QCoreApplication.translate("ImageStackWidget", u"Dimensions:", None)) + self.imagePixelOutputLabel.setText(QCoreApplication.translate("ImageStackWidget", u"AxBxC px", None)) + self.overrideScalingCheckBox.setText(QCoreApplication.translate("ImageStackWidget", u"Override pre-dertermined scaling", None)) + self.label_2.setText(QCoreApplication.translate("ImageStackWidget", u"Scaling:", None)) + # retranslateUi +