pyobs-gui 2.0.0.dev8__tar.gz → 2.0.0.dev10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/PKG-INFO +1 -1
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/acquisitionwidget.py +12 -3
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/camerawidget.py +10 -6
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyproject.toml +1 -1
- pyobs_gui-2.0.0.dev10/tests/test_camerawidget.py +85 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/uv.lock +1 -1
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.claude/skills/verify/SKILL.md +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.github/dependabot.yml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.github/workflows/pypi.yml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.github/workflows/pyrefly.yml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.github/workflows/ruff.yml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.gitignore +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.pre-commit-config.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/.readthedocs.yml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/CHANGELOG.rst +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/LICENSE +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/README.md +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/bin/mypyuic5 +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/docs/Makefile +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/docs/make.bat +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/docs/requirements.txt +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/docs/source/_static/pyobs.gif +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/docs/source/conf.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/docs/source/index.rst +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/mypy.ini +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/__init__.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/__main__.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/_nuitka_astropy_patch.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/accounts.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/autofocuswidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/autoguidingwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/base.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/commandinputwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/compassmovewidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/coolingwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/datadisplaywidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/eventswidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/filterwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/fitsheaderswidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/focuswidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/gui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/login.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/loginwindow.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/logmodel.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/mainwindow.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/modewidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/modifiedmixin.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/modulegui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/__init__.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/acquisitionwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/acquisitionwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/autofocuswidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/autofocuswidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/autoguidingwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/autoguidingwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/camerawidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/camerawidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/compassmoveplugin.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/compassmovewidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/compassmovewidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/compassmovewidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/compile.sh +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/coolingwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/coolingwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/datadisplayplugin.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/datadisplaywidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/datadisplaywidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/designer.sh +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/eventswidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/eventswidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/filterwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/filterwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/fitsheaderswidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/fitsheaderswidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/focuswidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/focuswidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/mainwindow.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/mainwindow_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/modewidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/modewidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrow-alt-circle-down-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrow-alt-circle-left-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrow-alt-circle-right-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrow-alt-circle-up-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrow-up-right-from-square-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrows-to-eye-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/chart-line-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/circle-question-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/cloud-sun-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/edit-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/search-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/undo-solid.svg +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources.qrc +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources_rc.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/roofwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/roofwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/shellwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/shellwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/spectrographwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/spectrographwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/telescopewidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/telescopewidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/temperaturesplotwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/temperaturesplotwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/temperatureswidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/temperatureswidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/videowidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/videowidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/weatherwidget.ui +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/weatherwidget_ui.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/roofwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/shellwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/spectrographwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/statuswidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/telescopewidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/temperaturesplotwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/temperatureswidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/utils.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/videowidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/watchedlabel.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/weatherwidget.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pysidedeploy.spec +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/specs/README.md +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/spike_standalone/main.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/spike_standalone/pysidedeploy.spec +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/acquisition.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/autofocus.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/camera.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/full.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/guiding.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/mode.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/roof.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/spectrograph.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/telescope.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/telescope_acl.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/telescope_acl_denied.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/test/video.yaml +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/tests/__init__.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/tests/conftest.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/tests/test_accounts.py +0 -0
- {pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/tests/test_loginwindow.py +0 -0
|
@@ -123,19 +123,28 @@ class AcquisitionWidget(BaseWidget, Ui_AcquisitionWidget):
|
|
|
123
123
|
xlabel, ylabel = "Offset 1 [deg]", "Offset 2 [deg]"
|
|
124
124
|
if points:
|
|
125
125
|
xs, ys = zip(*points, strict=True)
|
|
126
|
-
self.ax2.axhline(0, color="gray", linewidth=0.5)
|
|
127
|
-
self.ax2.axvline(0, color="gray", linewidth=0.5)
|
|
128
126
|
self.ax2.plot(xs, ys, marker="o", color="tab:orange")
|
|
129
127
|
self.ax2.plot(xs[0], ys[0], marker="s", color="tab:red", markersize=8, linestyle="", label="start")
|
|
130
128
|
self.ax2.plot(xs[-1], ys[-1], marker="*", color="tab:green", markersize=12, linestyle="", label="latest")
|
|
131
129
|
self.ax2.legend(fontsize="small")
|
|
132
|
-
self.ax2.set_aspect("equal", adjustable="datalim")
|
|
133
130
|
self.ax2.set_xlabel(xlabel)
|
|
134
131
|
self.ax2.set_ylabel(ylabel)
|
|
135
132
|
self.ax2.grid(linestyle=":", alpha=0.5)
|
|
136
133
|
self.ax2.set_axisbelow(True)
|
|
137
134
|
|
|
138
135
|
self.figure.tight_layout()
|
|
136
|
+
|
|
137
|
+
if points:
|
|
138
|
+
# lock in the aspect/view from the actual data -- after tight_layout, so the axes
|
|
139
|
+
# box size is already final -- before adding the crosshair lines below, which
|
|
140
|
+
# otherwise feed (0, 0) into the data limits and force the plot to zoom out to
|
|
141
|
+
# include the origin even when every point is far from it
|
|
142
|
+
self.ax2.set_aspect("equal", adjustable="datalim")
|
|
143
|
+
self.ax2.apply_aspect()
|
|
144
|
+
self.ax2.autoscale(False)
|
|
145
|
+
self.ax2.axhline(0, color="gray", linewidth=0.5, zorder=0)
|
|
146
|
+
self.ax2.axvline(0, color="gray", linewidth=0.5, zorder=0)
|
|
147
|
+
|
|
139
148
|
self.canvas.draw()
|
|
140
149
|
|
|
141
150
|
@qasync.asyncSlot() # type: ignore
|
|
@@ -332,13 +332,17 @@ class CameraWidget(BaseWidget, Ui_CameraWidget):
|
|
|
332
332
|
self.exposures_left = self.spinCount.value()
|
|
333
333
|
broadcast = self.checkBroadcast.isChecked()
|
|
334
334
|
|
|
335
|
-
# if the module can grab a counted sequence server-side, let it
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
335
|
+
# if the module can grab a counted sequence server-side, let it -- but only when
|
|
336
|
+
# broadcasting, since grab_sequence() doesn't hand filenames back to the caller and
|
|
337
|
+
# the client has no other way to learn an image is ready to display
|
|
338
|
+
if broadcast:
|
|
339
|
+
async with self.comm.safe_proxy(self.module, IDataSequence) as proxy:
|
|
340
|
+
if proxy is not None:
|
|
341
|
+
await proxy.grab_sequence(self.exposures_left, broadcast)
|
|
342
|
+
return
|
|
340
343
|
|
|
341
|
-
# fall back to a client-side loop for modules that don't support IDataSequence
|
|
344
|
+
# fall back to a client-side loop for modules that don't support IDataSequence, or
|
|
345
|
+
# when not broadcasting (grab_data() returns the filename directly for display)
|
|
342
346
|
while self.exposures_left > 0:
|
|
343
347
|
await self.datadisplay.grab_data(broadcast)
|
|
344
348
|
self.exposures_left -= 1
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from types import SimpleNamespace
|
|
2
|
+
from unittest.mock import AsyncMock
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from pyobs.interfaces import IDataSequence
|
|
7
|
+
from pyobs_gui.camerawidget import CameraWidget
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class _AsyncProxyCM:
|
|
11
|
+
"""Mimics Comm.safe_proxy()'s async context manager, yielding a fixed proxy (or None)."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, value):
|
|
14
|
+
self._value = value
|
|
15
|
+
|
|
16
|
+
async def __aenter__(self):
|
|
17
|
+
return self._value
|
|
18
|
+
|
|
19
|
+
async def __aexit__(self, *exc_info):
|
|
20
|
+
return False
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class FakeComm:
|
|
24
|
+
"""Only implements what CameraWidget.expose() touches; every optional interface except
|
|
25
|
+
IDataSequence resolves to "not supported" (proxy is None)."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, data_sequence_proxy=None):
|
|
28
|
+
self._data_sequence_proxy = data_sequence_proxy
|
|
29
|
+
|
|
30
|
+
def safe_proxy(self, module, interface):
|
|
31
|
+
value = self._data_sequence_proxy if interface is IDataSequence else None
|
|
32
|
+
return _AsyncProxyCM(value)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def make_widget(data_sequence_proxy) -> CameraWidget:
|
|
36
|
+
widget = CameraWidget()
|
|
37
|
+
widget.modules = ["camera"]
|
|
38
|
+
widget._comm = FakeComm(data_sequence_proxy=data_sequence_proxy)
|
|
39
|
+
widget.datadisplay.grab_data = AsyncMock()
|
|
40
|
+
return widget
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.mark.asyncio
|
|
44
|
+
async def test_expose_uses_server_side_sequence_when_broadcasting(qapp) -> None:
|
|
45
|
+
proxy = SimpleNamespace(grab_sequence=AsyncMock())
|
|
46
|
+
widget = make_widget(proxy)
|
|
47
|
+
widget.checkBroadcast.setChecked(True)
|
|
48
|
+
widget.spinCount.setValue(3)
|
|
49
|
+
|
|
50
|
+
await widget.expose()
|
|
51
|
+
|
|
52
|
+
proxy.grab_sequence.assert_awaited_once_with(3, True)
|
|
53
|
+
widget.datadisplay.grab_data.assert_not_called()
|
|
54
|
+
widget.close()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.mark.asyncio
|
|
58
|
+
async def test_expose_falls_back_to_client_side_loop_when_not_broadcasting(qapp) -> None:
|
|
59
|
+
"""Regression test: grab_sequence() has no way to hand a filename back to the caller, so
|
|
60
|
+
without broadcasting, taking the server-side sequence path would leave the GUI with no way
|
|
61
|
+
to learn an image is ready and nothing would ever be displayed (issue #122)."""
|
|
62
|
+
proxy = SimpleNamespace(grab_sequence=AsyncMock())
|
|
63
|
+
widget = make_widget(proxy)
|
|
64
|
+
widget.checkBroadcast.setChecked(False)
|
|
65
|
+
widget.spinCount.setValue(2)
|
|
66
|
+
|
|
67
|
+
await widget.expose()
|
|
68
|
+
|
|
69
|
+
proxy.grab_sequence.assert_not_called()
|
|
70
|
+
assert widget.datadisplay.grab_data.await_count == 2
|
|
71
|
+
widget.datadisplay.grab_data.assert_awaited_with(False)
|
|
72
|
+
widget.close()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@pytest.mark.asyncio
|
|
76
|
+
async def test_expose_falls_back_when_module_has_no_data_sequence_support(qapp) -> None:
|
|
77
|
+
widget = make_widget(data_sequence_proxy=None)
|
|
78
|
+
widget.checkBroadcast.setChecked(True)
|
|
79
|
+
widget.spinCount.setValue(1)
|
|
80
|
+
|
|
81
|
+
await widget.expose()
|
|
82
|
+
|
|
83
|
+
assert widget.datadisplay.grab_data.await_count == 1
|
|
84
|
+
widget.datadisplay.grab_data.assert_awaited_with(True)
|
|
85
|
+
widget.close()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrow-alt-circle-up-solid.svg
RENAMED
|
File without changes
|
|
File without changes
|
{pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/arrows-to-eye-solid.svg
RENAMED
|
File without changes
|
|
File without changes
|
{pyobs_gui-2.0.0.dev8 → pyobs_gui-2.0.0.dev10}/pyobs_gui/qt/resources/circle-question-solid.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|