butterfly_viewer.aux_dialogs
QDialog widgets for SplitView.
Not intended as a script. Used in Butterfly Viewer.
Creates a dialog window for users to calculate the pixel-unit conversion for rulers in SplitView.
1#!/usr/bin/env python3 2 3"""QDialog widgets for SplitView. 4 5Not intended as a script. Used in Butterfly Viewer. 6 7Creates a dialog window for users to calculate the pixel-unit conversion for rulers in SplitView. 8""" 9# SPDX-License-Identifier: GPL-3.0-or-later 10 11 12 13from PyQt5 import QtWidgets, QtCore 14 15 16 17class PixelUnitConversionInputDialog(QtWidgets.QDialog): 18 """Create a dialog window to calculate the conversion for pixels to other units of length in SplitView. 19 20 Currently only supports millimeters. 21 Emits the value of the px-per-mm conversion if user clicks "Ok" on dialog. 22 23 Args: 24 parent: Do not set OR only set to None. 25 unit (str): Unit of length to which to convert from pixels, abbreviated. 26 Currently only supports "mm" (millimeters). 27 px_conversion (float): Quantity of pixels in a known distance. 28 unit_conversion (float): Quantity of the specified unit of length in a known distance. 29 px_per_unit (float): Pixel-per-unit conversion. Set to None if not previously calculated. 30 """ 31 32 def __init__(self, parent=None, unit="mm", px_conversion=1.0, unit_conversion=1.0, px_per_unit=None): 33 super().__init__(parent) 34 self.setWindowTitle("Set conversion factor for pixel-per-" + unit + " conversion for this image window") 35 self.setWindowFlags(QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) 36 37 frame_rect = self.frameGeometry() 38 center_point = QtWidgets.QDesktopWidget().availableGeometry().center() 39 frame_rect.moveCenter(center_point) 40 self.move(frame_rect.topLeft()) 41 42 self.unit = unit 43 if unit == "mm": 44 self.unit_longform = "millimeter" 45 self.unit_longform_cap = "Millimeter" 46 else: 47 self.unit_longform = unit 48 self.unit_longform_cap = self.unit_longform 49 self.px_conversion = px_conversion # e.g., 100 pixels 50 self.unit_conversion = unit_conversion # e.g., 50 mm 51 self.px_per_unit = px_per_unit 52 if self.px_per_unit is None: 53 self.px_per_unit = self.px_conversion/self.unit_conversion # e.g., 100 px per 50 mm = 2 px/mm 54 55 buttonbox = QtWidgets.QDialogButtonBox() 56 buttonbox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) 57 buttonbox.accepted.connect(self.accept) 58 buttonbox.rejected.connect(self.reject) 59 60 dialog_string = "Enter the pixel and " + self.unit_longform + " length for a known distance in the base image of the active window." 61 dialog_string = dialog_string + "\n\n" + "Tip: First use a pixel ruler to measure a known distance in the image (such as the width of a painting canvas or the length of a calibration ruler) and then enter the distance in pixels and " + self.unit_longform + "s here.\n" 62 dialog_label = QtWidgets.QLabel(dialog_string) 63 dialog_label.setWordWrap(True) 64 65 values_layout = QtWidgets.QGridLayout() 66 px_label = QtWidgets.QLabel("Pixels in a known distance: ") 67 px_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) 68 px_string = "{:.2f}".format(self.px_conversion) 69 self.px_textedit = QtWidgets.QLineEdit(px_string) 70 self.px_textedit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) 71 self.px_textedit.textEdited.connect(self.on_px_textedit_edited) 72 self.px_textedit.editingFinished.connect(lambda: self.px_textedit.setText("{:.2f}".format(self.px_conversion))) 73 74 unit_label = QtWidgets.QLabel(self.unit_longform_cap + "s" + " in a known distance: ") 75 unit_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) 76 unit_string = "{:.2f}".format(self.unit_conversion) # + " " + "px" 77 self.unit_textedit = QtWidgets.QLineEdit(unit_string) 78 self.unit_textedit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) 79 self.unit_textedit.textEdited.connect(self.on_unit_textedit_edited) 80 self.unit_textedit.editingFinished.connect(lambda: self.unit_textedit.setText("{:.2f}".format(self.unit_conversion))) 81 82 px_per_unit_label = QtWidgets.QLabel("Calculated pixels per " + self.unit_longform + " for the known distance: ") 83 px_per_unit_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) 84 px_per_unit_string = "{:.2f}".format(self.px_per_unit) 85 self.px_per_unit_textedit = QtWidgets.QLineEdit(px_per_unit_string) 86 self.px_per_unit_textedit.setStyleSheet(""" 87 QLineEdit { 88 background-color: transparent; 89 border: 0px transparent; 90 } 91 """) 92 self.px_per_unit_textedit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) 93 self.px_per_unit_textedit.setReadOnly(True) 94 95 values_layout.addWidget(px_label, 0, 0) 96 values_layout.addWidget(self.px_textedit, 0, 1) 97 values_layout.addWidget(unit_label, 1, 0) 98 values_layout.addWidget(self.unit_textedit, 1, 1) 99 values_layout.addWidget(px_per_unit_label, 2, 0) 100 values_layout.addWidget(self.px_per_unit_textedit, 2, 1) 101 102 values_layout_widget = QtWidgets.QWidget() 103 values_layout_widget.setLayout(values_layout) 104 105 layout = QtWidgets.QGridLayout() 106 self.setLayout(layout) 107 108 layout.addWidget(dialog_label) 109 layout.addWidget(values_layout_widget) 110 layout.addWidget(buttonbox) 111 112 self.setStyleSheet("font-size: 9pt") 113 114 def on_px_textedit_edited(self, text): 115 """Filter and correct text typed into pixel field. 116 117 Corrects the following: 118 Decimal comma to decimal point (0,2 > 0.2). 119 No leading zero to leading zero (.2 > 0.2). 120 Hanging decimal to zero in tenths place (2. > 2.0). 121 122 Filters: 123 Non-numeric text. 124 Non float-to-text convertible numbers. 125 Zeroes (distances cannot be zero). 126 127 Triggered by QLineEdit.textEdited. 128 129 Args: 130 text (str): From QLineEdit.textEdited. 131 """ 132 if text is None: 133 return 134 text = text.replace(" ", "") 135 if text is "": 136 return 137 text = text.replace(",", ".") 138 text_filter = text 139 text_filter = text.replace(".", "") 140 if not text_filter.isnumeric(): 141 return 142 if text.endswith("."): 143 text.replace(".", ".0") 144 if text.startswith("."): 145 text.replace(".", "0.") 146 147 try: 148 px_conversion = float(text) 149 except: 150 return 151 152 try: #: Ensure not zero. 153 1/px_conversion 154 except: 155 return 156 157 self.px_conversion = px_conversion 158 self.px_per_unit = self.px_conversion/self.unit_conversion 159 self.px_per_unit_textedit.setText("{:.2f}".format(self.px_per_unit)) 160 161 def on_unit_textedit_edited(self, text): 162 """Filter and correct text typed into unit of length field. 163 164 Corrects the following: 165 Decimal comma to decimal point (0,2 > 0.2). 166 No leading zero to leading zero (.2 > 0.2). 167 Hanging decimal to zero in tenths place (2. > 2.0). 168 169 Filters: 170 Non-numeric text. 171 Non float-to-text convertible numbers. 172 Zeroes. 173 174 Triggered by QLineEdit.textEdited. 175 176 Args: 177 text (str): From QLineEdit.textEdited. 178 """ 179 if text is None: 180 return 181 text = text.replace(" ", "") 182 if text is "": 183 return 184 text = text.replace(",", ".") 185 text_filter = text 186 text_filter = text.replace(".", "") 187 if not text_filter.isnumeric(): 188 return 189 if text.endswith("."): 190 text.replace(".", ".0") 191 if text.startswith("."): 192 text.replace(".", "0.") 193 194 try: 195 unit_conversion = float(text) 196 except: 197 return 198 199 try: #: Ensure not dividing by zero. 200 px_per_unit = self.px_conversion/unit_conversion 201 except: 202 return 203 204 self.unit_conversion = unit_conversion 205 self.px_per_unit = px_per_unit 206 self.px_per_unit_textedit.setText("{:.2f}".format(self.px_per_unit))
18class PixelUnitConversionInputDialog(QtWidgets.QDialog): 19 """Create a dialog window to calculate the conversion for pixels to other units of length in SplitView. 20 21 Currently only supports millimeters. 22 Emits the value of the px-per-mm conversion if user clicks "Ok" on dialog. 23 24 Args: 25 parent: Do not set OR only set to None. 26 unit (str): Unit of length to which to convert from pixels, abbreviated. 27 Currently only supports "mm" (millimeters). 28 px_conversion (float): Quantity of pixels in a known distance. 29 unit_conversion (float): Quantity of the specified unit of length in a known distance. 30 px_per_unit (float): Pixel-per-unit conversion. Set to None if not previously calculated. 31 """ 32 33 def __init__(self, parent=None, unit="mm", px_conversion=1.0, unit_conversion=1.0, px_per_unit=None): 34 super().__init__(parent) 35 self.setWindowTitle("Set conversion factor for pixel-per-" + unit + " conversion for this image window") 36 self.setWindowFlags(QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) 37 38 frame_rect = self.frameGeometry() 39 center_point = QtWidgets.QDesktopWidget().availableGeometry().center() 40 frame_rect.moveCenter(center_point) 41 self.move(frame_rect.topLeft()) 42 43 self.unit = unit 44 if unit == "mm": 45 self.unit_longform = "millimeter" 46 self.unit_longform_cap = "Millimeter" 47 else: 48 self.unit_longform = unit 49 self.unit_longform_cap = self.unit_longform 50 self.px_conversion = px_conversion # e.g., 100 pixels 51 self.unit_conversion = unit_conversion # e.g., 50 mm 52 self.px_per_unit = px_per_unit 53 if self.px_per_unit is None: 54 self.px_per_unit = self.px_conversion/self.unit_conversion # e.g., 100 px per 50 mm = 2 px/mm 55 56 buttonbox = QtWidgets.QDialogButtonBox() 57 buttonbox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) 58 buttonbox.accepted.connect(self.accept) 59 buttonbox.rejected.connect(self.reject) 60 61 dialog_string = "Enter the pixel and " + self.unit_longform + " length for a known distance in the base image of the active window." 62 dialog_string = dialog_string + "\n\n" + "Tip: First use a pixel ruler to measure a known distance in the image (such as the width of a painting canvas or the length of a calibration ruler) and then enter the distance in pixels and " + self.unit_longform + "s here.\n" 63 dialog_label = QtWidgets.QLabel(dialog_string) 64 dialog_label.setWordWrap(True) 65 66 values_layout = QtWidgets.QGridLayout() 67 px_label = QtWidgets.QLabel("Pixels in a known distance: ") 68 px_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) 69 px_string = "{:.2f}".format(self.px_conversion) 70 self.px_textedit = QtWidgets.QLineEdit(px_string) 71 self.px_textedit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) 72 self.px_textedit.textEdited.connect(self.on_px_textedit_edited) 73 self.px_textedit.editingFinished.connect(lambda: self.px_textedit.setText("{:.2f}".format(self.px_conversion))) 74 75 unit_label = QtWidgets.QLabel(self.unit_longform_cap + "s" + " in a known distance: ") 76 unit_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) 77 unit_string = "{:.2f}".format(self.unit_conversion) # + " " + "px" 78 self.unit_textedit = QtWidgets.QLineEdit(unit_string) 79 self.unit_textedit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) 80 self.unit_textedit.textEdited.connect(self.on_unit_textedit_edited) 81 self.unit_textedit.editingFinished.connect(lambda: self.unit_textedit.setText("{:.2f}".format(self.unit_conversion))) 82 83 px_per_unit_label = QtWidgets.QLabel("Calculated pixels per " + self.unit_longform + " for the known distance: ") 84 px_per_unit_label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) 85 px_per_unit_string = "{:.2f}".format(self.px_per_unit) 86 self.px_per_unit_textedit = QtWidgets.QLineEdit(px_per_unit_string) 87 self.px_per_unit_textedit.setStyleSheet(""" 88 QLineEdit { 89 background-color: transparent; 90 border: 0px transparent; 91 } 92 """) 93 self.px_per_unit_textedit.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) 94 self.px_per_unit_textedit.setReadOnly(True) 95 96 values_layout.addWidget(px_label, 0, 0) 97 values_layout.addWidget(self.px_textedit, 0, 1) 98 values_layout.addWidget(unit_label, 1, 0) 99 values_layout.addWidget(self.unit_textedit, 1, 1) 100 values_layout.addWidget(px_per_unit_label, 2, 0) 101 values_layout.addWidget(self.px_per_unit_textedit, 2, 1) 102 103 values_layout_widget = QtWidgets.QWidget() 104 values_layout_widget.setLayout(values_layout) 105 106 layout = QtWidgets.QGridLayout() 107 self.setLayout(layout) 108 109 layout.addWidget(dialog_label) 110 layout.addWidget(values_layout_widget) 111 layout.addWidget(buttonbox) 112 113 self.setStyleSheet("font-size: 9pt") 114 115 def on_px_textedit_edited(self, text): 116 """Filter and correct text typed into pixel field. 117 118 Corrects the following: 119 Decimal comma to decimal point (0,2 > 0.2). 120 No leading zero to leading zero (.2 > 0.2). 121 Hanging decimal to zero in tenths place (2. > 2.0). 122 123 Filters: 124 Non-numeric text. 125 Non float-to-text convertible numbers. 126 Zeroes (distances cannot be zero). 127 128 Triggered by QLineEdit.textEdited. 129 130 Args: 131 text (str): From QLineEdit.textEdited. 132 """ 133 if text is None: 134 return 135 text = text.replace(" ", "") 136 if text is "": 137 return 138 text = text.replace(",", ".") 139 text_filter = text 140 text_filter = text.replace(".", "") 141 if not text_filter.isnumeric(): 142 return 143 if text.endswith("."): 144 text.replace(".", ".0") 145 if text.startswith("."): 146 text.replace(".", "0.") 147 148 try: 149 px_conversion = float(text) 150 except: 151 return 152 153 try: #: Ensure not zero. 154 1/px_conversion 155 except: 156 return 157 158 self.px_conversion = px_conversion 159 self.px_per_unit = self.px_conversion/self.unit_conversion 160 self.px_per_unit_textedit.setText("{:.2f}".format(self.px_per_unit)) 161 162 def on_unit_textedit_edited(self, text): 163 """Filter and correct text typed into unit of length field. 164 165 Corrects the following: 166 Decimal comma to decimal point (0,2 > 0.2). 167 No leading zero to leading zero (.2 > 0.2). 168 Hanging decimal to zero in tenths place (2. > 2.0). 169 170 Filters: 171 Non-numeric text. 172 Non float-to-text convertible numbers. 173 Zeroes. 174 175 Triggered by QLineEdit.textEdited. 176 177 Args: 178 text (str): From QLineEdit.textEdited. 179 """ 180 if text is None: 181 return 182 text = text.replace(" ", "") 183 if text is "": 184 return 185 text = text.replace(",", ".") 186 text_filter = text 187 text_filter = text.replace(".", "") 188 if not text_filter.isnumeric(): 189 return 190 if text.endswith("."): 191 text.replace(".", ".0") 192 if text.startswith("."): 193 text.replace(".", "0.") 194 195 try: 196 unit_conversion = float(text) 197 except: 198 return 199 200 try: #: Ensure not dividing by zero. 201 px_per_unit = self.px_conversion/unit_conversion 202 except: 203 return 204 205 self.unit_conversion = unit_conversion 206 self.px_per_unit = px_per_unit 207 self.px_per_unit_textedit.setText("{:.2f}".format(self.px_per_unit))
Create a dialog window to calculate the conversion for pixels to other units of length in SplitView.
Currently only supports millimeters. Emits the value of the px-per-mm conversion if user clicks "Ok" on dialog.
Arguments:
- parent: Do not set OR only set to None.
- unit (str): Unit of length to which to convert from pixels, abbreviated. Currently only supports "mm" (millimeters).
- px_conversion (float): Quantity of pixels in a known distance.
- unit_conversion (float): Quantity of the specified unit of length in a known distance.
- px_per_unit (float): Pixel-per-unit conversion. Set to None if not previously calculated.
115 def on_px_textedit_edited(self, text): 116 """Filter and correct text typed into pixel field. 117 118 Corrects the following: 119 Decimal comma to decimal point (0,2 > 0.2). 120 No leading zero to leading zero (.2 > 0.2). 121 Hanging decimal to zero in tenths place (2. > 2.0). 122 123 Filters: 124 Non-numeric text. 125 Non float-to-text convertible numbers. 126 Zeroes (distances cannot be zero). 127 128 Triggered by QLineEdit.textEdited. 129 130 Args: 131 text (str): From QLineEdit.textEdited. 132 """ 133 if text is None: 134 return 135 text = text.replace(" ", "") 136 if text is "": 137 return 138 text = text.replace(",", ".") 139 text_filter = text 140 text_filter = text.replace(".", "") 141 if not text_filter.isnumeric(): 142 return 143 if text.endswith("."): 144 text.replace(".", ".0") 145 if text.startswith("."): 146 text.replace(".", "0.") 147 148 try: 149 px_conversion = float(text) 150 except: 151 return 152 153 try: #: Ensure not zero. 154 1/px_conversion 155 except: 156 return 157 158 self.px_conversion = px_conversion 159 self.px_per_unit = self.px_conversion/self.unit_conversion 160 self.px_per_unit_textedit.setText("{:.2f}".format(self.px_per_unit))
Filter and correct text typed into pixel field.
Corrects the following:
Decimal comma to decimal point (0,2 > 0.2). No leading zero to leading zero (.2 > 0.2). Hanging decimal to zero in tenths place (2. > 2.0).
Filters:
Non-numeric text. Non float-to-text convertible numbers. Zeroes (distances cannot be zero).
Triggered by QLineEdit.textEdited.
Arguments:
- text (str): From QLineEdit.textEdited.
162 def on_unit_textedit_edited(self, text): 163 """Filter and correct text typed into unit of length field. 164 165 Corrects the following: 166 Decimal comma to decimal point (0,2 > 0.2). 167 No leading zero to leading zero (.2 > 0.2). 168 Hanging decimal to zero in tenths place (2. > 2.0). 169 170 Filters: 171 Non-numeric text. 172 Non float-to-text convertible numbers. 173 Zeroes. 174 175 Triggered by QLineEdit.textEdited. 176 177 Args: 178 text (str): From QLineEdit.textEdited. 179 """ 180 if text is None: 181 return 182 text = text.replace(" ", "") 183 if text is "": 184 return 185 text = text.replace(",", ".") 186 text_filter = text 187 text_filter = text.replace(".", "") 188 if not text_filter.isnumeric(): 189 return 190 if text.endswith("."): 191 text.replace(".", ".0") 192 if text.startswith("."): 193 text.replace(".", "0.") 194 195 try: 196 unit_conversion = float(text) 197 except: 198 return 199 200 try: #: Ensure not dividing by zero. 201 px_per_unit = self.px_conversion/unit_conversion 202 except: 203 return 204 205 self.unit_conversion = unit_conversion 206 self.px_per_unit = px_per_unit 207 self.px_per_unit_textedit.setText("{:.2f}".format(self.px_per_unit))
Filter and correct text typed into unit of length field.
Corrects the following:
Decimal comma to decimal point (0,2 > 0.2). No leading zero to leading zero (.2 > 0.2). Hanging decimal to zero in tenths place (2. > 2.0).
Filters:
Non-numeric text. Non float-to-text convertible numbers. Zeroes.
Triggered by QLineEdit.textEdited.
Arguments:
- text (str): From QLineEdit.textEdited.