Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into configs
Browse files Browse the repository at this point in the history
  • Loading branch information
fdrgsp committed Jul 16, 2024
2 parents afee5c8 + 5957860 commit 3f20ab8
Show file tree
Hide file tree
Showing 19 changed files with 1,813 additions and 45 deletions.
21 changes: 21 additions & 0 deletions examples/points_plan_widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from qtpy.QtWidgets import QApplication
from useq import RandomPoints

from pymmcore_widgets.useq_widgets import PointsPlanWidget

app = QApplication([])

points = RandomPoints(
num_points=60,
allow_overlap=False,
fov_width=300,
fov_height=200,
max_width=4000,
max_height=4000,
)

fs = PointsPlanWidget(points)
fs.setWellSize(6, 6)
fs.show()

app.exec()
22 changes: 22 additions & 0 deletions examples/well_plate_widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from contextlib import suppress

import useq
from qtpy.QtWidgets import QApplication

from pymmcore_widgets.useq_widgets import WellPlateWidget

with suppress(ImportError):
from rich import print


app = QApplication([])

plan = useq.WellPlatePlan(
plate="24-well", a1_center_xy=(0, 0), selected_wells=slice(0, 8, 2)
)

ps = WellPlateWidget(plan)
ps.valueChanged.connect(print)
ps.show()

app.exec()
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ dependencies = [
'pymmcore-plus[cli] >=0.11.0',
'qtpy >=2.0',
'superqt[quantity] >=0.5.3',
'useq-schema >=0.4.7',
'useq-schema @ git+https://github.com/pymmcore-plus/useq-schema.git', # temporary until new useq release
]

[tool.hatch.metadata]
allow-direct-references = true

# extras
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
[project.optional-dependencies]
Expand Down Expand Up @@ -174,4 +177,5 @@ ignore = [
]

[tool.typos.default]
extend-ignore-identifiers-re = ["(?i)ome"]
extend-ignore-identifiers-re = ["(?i)nd2?.*", "(?i)ome", "FO(Vs?)?"]

10 changes: 8 additions & 2 deletions src/pymmcore_widgets/_group_preset_widget/_edit_group_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def __init__(self, group: str, *, parent: QWidget | None = None) -> None:
self._create_gui()

self.group_lineedit.setText(self._group)
self.group_lineedit.setEnabled(False)

self.destroyed.connect(self._disconnect)

Expand Down Expand Up @@ -144,6 +143,13 @@ def _update_filter(self) -> None:
)

def _add_group(self) -> None:
# rename group if it has been changed
renamed: bool = False
if self._group != self.group_lineedit.text():
self._mmc.renameConfigGroup(self._group, self.group_lineedit.text())
self._group = self.group_lineedit.text()
renamed = True

# [(device, property, value), ...], need to remove the value
new_dev_prop = [x[:2] for x in self._prop_table.getCheckedProperties()]

Expand All @@ -152,7 +158,7 @@ def _add_group(self) -> None:
(k[0], k[1]) for k in self._mmc.getConfigData(self._group, presets[0])
]

if preset_dev_prop == new_dev_prop:
if preset_dev_prop == new_dev_prop and not renamed:
return

# get any new dev prop to add to each preset
Expand Down
34 changes: 33 additions & 1 deletion src/pymmcore_widgets/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
import useq
from psygnal import SignalInstance
from pymmcore_plus import CMMCorePlus
from qtpy.QtCore import QObject
from qtpy.QtCore import QMarginsF, QObject, Qt
from qtpy.QtGui import QPainter, QPaintEvent, QPen, QResizeEvent
from qtpy.QtWidgets import (
QComboBox,
QDialog,
QDialogButtonBox,
QGraphicsScene,
QGraphicsView,
QLabel,
QVBoxLayout,
QWidget,
Expand Down Expand Up @@ -176,3 +179,32 @@ def get_next_available_path(requested_path: Path | str, min_digits: int = 3) ->
# use it
current_max = max(int(num), current_max)
return directory / f"{stem}_{current_max:0{min_digits}d}{extension}"


class SeparatorWidget(QWidget):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.setFixedHeight(1)

def paintEvent(self, a0: QPaintEvent | None) -> None:
painter = QPainter(self)
painter.setPen(QPen(Qt.GlobalColor.gray, 1, Qt.PenStyle.SolidLine))
painter.drawLine(self.rect().topLeft(), self.rect().topRight())


class ResizingGraphicsView(QGraphicsView):
"""A QGraphicsView that resizes the scene to fit the view."""

def __init__(self, scene: QGraphicsScene, parent: QWidget | None = None) -> None:
super().__init__(scene, parent)
self.padding = 0.05 # fraction of the bounding rect

def resizeEvent(self, event: QResizeEvent | None) -> None:
if not (scene := self.scene()):
return
rect = scene.itemsBoundingRect()
xmargin = rect.width() * self.padding
ymargin = rect.height() * self.padding
margins = QMarginsF(xmargin, ymargin, xmargin, ymargin)
self.fitInView(rect.marginsAdded(margins), Qt.AspectRatioMode.KeepAspectRatio)
super().resizeEvent(event)
24 changes: 14 additions & 10 deletions src/pymmcore_widgets/useq_widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,26 @@
from ._mda_sequence import PYMMCW_METADATA_KEY, MDASequenceWidget
from ._positions import PositionTable
from ._time import TimePlanWidget
from ._well_plate_widget import WellPlateWidget
from ._z import ZPlanWidget
from .points_plans import PointsPlanWidget

__all__ = [
"PositionTable",
"BoolColumn",
"ChannelTable",
"DataTableWidget",
"TimePlanWidget",
"DataTable",
"MDASequenceWidget",
"ChoiceColumn",
"GridPlanWidget",
"TextColumn",
"DataTable",
"DataTableWidget",
"FloatColumn",
"GridPlanWidget",
"IntColumn",
"ZPlanWidget",
"BoolColumn",
"TimeDeltaColumn",
"MDASequenceWidget",
"PointsPlanWidget",
"PositionTable",
"PYMMCW_METADATA_KEY",
"TextColumn",
"TimeDeltaColumn",
"TimePlanWidget",
"WellPlateWidget",
"ZPlanWidget",
]
20 changes: 5 additions & 15 deletions src/pymmcore_widgets/useq_widgets/_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import useq
from qtpy.QtCore import QSize, Qt, Signal
from qtpy.QtGui import QPainter, QPaintEvent, QPen
from qtpy.QtWidgets import (
QAbstractButton,
QButtonGroup,
Expand All @@ -23,6 +22,8 @@
from superqt import QEnumComboBox
from superqt.utils import signals_blocked

from pymmcore_widgets._util import SeparatorWidget


class RelativeTo(Enum):
center = "center"
Expand Down Expand Up @@ -166,11 +167,11 @@ def __init__(self, parent: QWidget | None = None):
inner_widget = QWidget(self)
layout = QVBoxLayout(inner_widget)
layout.addLayout(row_col_layout)
layout.addWidget(_SeparatorWidget())
layout.addWidget(SeparatorWidget())
layout.addLayout(width_height_layout) # hiding until useq supports it
layout.addWidget(_SeparatorWidget())
layout.addWidget(SeparatorWidget())
layout.addLayout(self.bounds_layout)
layout.addWidget(_SeparatorWidget())
layout.addWidget(SeparatorWidget())
layout.addLayout(bottom_stuff)
layout.addStretch()

Expand Down Expand Up @@ -361,14 +362,3 @@ def _on_change(self) -> None:
if (val := self.value()) is None:
return # pragma: no cover
self.valueChanged.emit(val)


class _SeparatorWidget(QWidget):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.setFixedHeight(1)

def paintEvent(self, a0: QPaintEvent | None) -> None:
painter = QPainter(self)
painter.setPen(QPen(Qt.GlobalColor.gray, 1, Qt.PenStyle.SolidLine))
painter.drawLine(self.rect().topLeft(), self.rect().topRight())
Loading

0 comments on commit 3f20ab8

Please sign in to comment.