pyobs-gui 2.2.0__tar.gz → 2.3.0__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.2.0 → pyobs_gui-2.3.0}/PKG-INFO +1 -1
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/__init__.py +1 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/camerawidget.py +16 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/mainwindow.py +16 -3
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/modewidget.py +9 -2
- pyobs_gui-2.3.0/pyobs_gui/qt/videograbwidget.ui +257 -0
- pyobs_gui-2.3.0/pyobs_gui/qt/videograbwidget_ui.py +146 -0
- pyobs_gui-2.3.0/pyobs_gui/qt/videowidget.ui +102 -0
- pyobs_gui-2.3.0/pyobs_gui/qt/videowidget_ui.py +101 -0
- pyobs_gui-2.3.0/pyobs_gui/videograbwidget.py +143 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/videowidget.py +7 -95
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyproject.toml +1 -1
- pyobs_gui-2.3.0/specs/2026-09-01-gui-video-widget-split.md +90 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/specs/index.md +4 -3
- pyobs_gui-2.3.0/tests/test_modewidget.py +72 -0
- pyobs_gui-2.3.0/tests/test_videograbwidget.py +38 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_videowidget.py +1 -34
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/uv.lock +1 -1
- pyobs_gui-2.2.0/pyobs_gui/qt/videowidget.ui +0 -1115
- pyobs_gui-2.2.0/pyobs_gui/qt/videowidget_ui.py +0 -354
- pyobs_gui-2.2.0/specs/2026-09-01-gui-video-widget-split.md +0 -107
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.claude/skills/verify/SKILL.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.github/dependabot.yml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.github/workflows/dependabot-automerge.yml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.github/workflows/pypi.yml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.github/workflows/pyrefly.yml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.github/workflows/ruff.yml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.gitignore +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.pre-commit-config.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/.readthedocs.yml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/CHANGELOG.rst +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/LICENSE +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/README.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/bin/mypyuic5 +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/docs/Makefile +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/docs/make.bat +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/docs/requirements.txt +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/docs/source/_static/pyobs.gif +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/docs/source/conf.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/docs/source/index.rst +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/mypy.ini +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/__main__.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/_nuitka_astropy_patch.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/accounts.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/acquisitionwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/autofocuswidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/autoguidingwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/base.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/commandinputwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/compassmovewidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/coolingwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/datadisplaywidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/eventswidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/filterwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/fitsheaderswidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/focuswidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/gui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/login.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/loginwindow.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/logmodel.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/modifiedmixin.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/modulegui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/__init__.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/acquisitionwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/acquisitionwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/autofocuswidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/autofocuswidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/autoguidingwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/autoguidingwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/camerawidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/camerawidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/compassmoveplugin.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/compassmovewidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/compassmovewidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/compassmovewidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/compile.sh +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/coolingwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/coolingwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/datadisplayplugin.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/datadisplaywidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/datadisplaywidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/designer.sh +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/eventswidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/eventswidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/filterwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/filterwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/fitsheaderswidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/fitsheaderswidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/focuswidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/focuswidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/mainwindow.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/mainwindow_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/modewidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/modewidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/arrow-alt-circle-down-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/arrow-alt-circle-left-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/arrow-alt-circle-right-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/arrow-alt-circle-up-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/arrow-up-right-from-square-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/arrows-to-eye-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/chart-line-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/circle-question-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/cloud-sun-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/edit-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/search-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources/undo-solid.svg +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources.qrc +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/resources_rc.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/roboticwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/roboticwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/roofwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/roofwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/schedulewidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/schedulewidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/shellwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/shellwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/spectrographwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/spectrographwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/telescopewidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/telescopewidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/temperaturesplotwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/temperaturesplotwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/temperatureswidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/temperatureswidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/weatherwidget.ui +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/qt/weatherwidget_ui.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/roboticwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/roofwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/schedulewidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/shellwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/spectrographwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/statuswidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/structuredconfigwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/telescopewidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/temperaturesplotwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/temperatureswidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/utils.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/watchedlabel.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pyobs_gui/weatherwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/pysidedeploy.spec +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/specs/2026-08-20-gui-remote-call-error-handling.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/specs/2026-08-21-gui-widget-startup-responsiveness.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/specs/2026-08-28-gui-main-vs-sidebar-widgets.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/specs/2026-08-28-structuredconfig-widget.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/specs/2026-08-31-irobotic-widgets.md +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/spike_standalone/main.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/spike_standalone/pysidedeploy.spec +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/acquisition.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/autofocus.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/camera.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/full.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/guiding.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/mode.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/robotic.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/roof.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/spectrograph.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/structuredconfig.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/telescope.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/telescope_acl.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/telescope_acl_denied.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/test/video.yaml +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/__init__.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/conftest.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_accounts.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_camerawidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_loginwindow.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_mainwindow_startup.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_multiwidget_pages.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_roboticwidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_schedulewidget.py +0 -0
- {pyobs_gui-2.2.0 → pyobs_gui-2.3.0}/tests/test_structuredconfigwidget.py +0 -0
|
@@ -17,6 +17,7 @@ from .datadisplaywidget import DataDisplayWidget
|
|
|
17
17
|
from .coolingwidget import CoolingWidget
|
|
18
18
|
from .shellwidget import ShellWidget
|
|
19
19
|
from .videowidget import VideoWidget
|
|
20
|
+
from .videograbwidget import VideoGrabWidget
|
|
20
21
|
from .focuswidget import FocusWidget
|
|
21
22
|
from .telescopewidget import TelescopeWidget
|
|
22
23
|
from .weatherwidget import WeatherWidget
|
|
@@ -57,6 +57,15 @@ class CameraWidget(BaseWidget, Ui_CameraWidget):
|
|
|
57
57
|
BaseWidget.__init__(self, **kwargs)
|
|
58
58
|
self.setupUi(self) # type: ignore
|
|
59
59
|
|
|
60
|
+
# scrollArea's horizontal scrollbar is off (this panel should never need to scroll
|
|
61
|
+
# sideways), but with widgetResizable=True that leaves nothing to widen the scroll area
|
|
62
|
+
# itself to fit its content -- it was clipping the right edge of every group box
|
|
63
|
+
# (values/buttons ran past the visible border) because the .ui's Designer-time width hint
|
|
64
|
+
# (239px) is narrower than the controls' actual required width. Size it from the real
|
|
65
|
+
# content instead of a hardcoded guess; recomputed again at the end of _init() once
|
|
66
|
+
# capability-dependent combo boxes (binning, image format) have their real items.
|
|
67
|
+
self._size_scroll_area_to_content()
|
|
68
|
+
|
|
60
69
|
# variables
|
|
61
70
|
self.new_image = False
|
|
62
71
|
self.image_filename = None
|
|
@@ -130,9 +139,16 @@ class CameraWidget(BaseWidget, Ui_CameraWidget):
|
|
|
130
139
|
self._init_once("data_sequence", self._init_data_sequence),
|
|
131
140
|
)
|
|
132
141
|
|
|
142
|
+
# capability-dependent combo boxes (binning, image format) may have widened the panel
|
|
143
|
+
# further, now that they're populated
|
|
144
|
+
self._size_scroll_area_to_content()
|
|
145
|
+
|
|
133
146
|
# update GUI
|
|
134
147
|
self.signal_update_gui.emit()
|
|
135
148
|
|
|
149
|
+
def _size_scroll_area_to_content(self) -> None:
|
|
150
|
+
self.scrollArea.setMinimumWidth(self.scrollAreaWidgetContents.sizeHint().width())
|
|
151
|
+
|
|
136
152
|
async def _init_window(self) -> None:
|
|
137
153
|
# window
|
|
138
154
|
window_caps = await self.comm.get_capabilities(self.module, IWindow)
|
|
@@ -53,6 +53,7 @@ from .telescopewidget import TelescopeWidget
|
|
|
53
53
|
from .focuswidget import FocusWidget
|
|
54
54
|
from .temperatureswidget import TemperaturesWidget
|
|
55
55
|
from .weatherwidget import WeatherWidget
|
|
56
|
+
from .videograbwidget import VideoGrabWidget
|
|
56
57
|
from .videowidget import VideoWidget
|
|
57
58
|
from .qt.mainwindow_ui import Ui_MainWindow
|
|
58
59
|
from .logmodel import LogModel, LogModelProxy
|
|
@@ -83,8 +84,11 @@ class MainWidgetEntry:
|
|
|
83
84
|
# cross-interface demotion: only promoted into `main` when nothing else matched (D1)
|
|
84
85
|
sidebar_preferred: bool = False
|
|
85
86
|
# same-interface pairing: always rendered together whenever this entry survives into `main`
|
|
86
|
-
# (D6); no MAIN_WIDGETS entry sets this yet
|
|
87
|
-
#
|
|
87
|
+
# (D6); no MAIN_WIDGETS entry sets this yet. specs/2026-09-01-gui-video-widget-split.md's
|
|
88
|
+
# original plan was going to be the first consumer, but VideoWidget ended up split into two
|
|
89
|
+
# independent same-interface entries (see the two IVideo rows below) instead -- each tab is
|
|
90
|
+
# fully self-contained, with no state to share across a widget boundary, so this mechanism
|
|
91
|
+
# wasn't needed after all.
|
|
88
92
|
paired_sidebar_widget: Optional[Type[BaseWidget]] = None
|
|
89
93
|
|
|
90
94
|
|
|
@@ -105,7 +109,16 @@ MAIN_WIDGETS: List[MainWidgetEntry] = [
|
|
|
105
109
|
MainWidgetEntry(IAcquisition, AcquisitionWidget, "Acquisition", "mdi.target"),
|
|
106
110
|
MainWidgetEntry(IAutoGuiding, AutoGuidingWidget, "Auto guiding", "mdi.crosshairs-gps"),
|
|
107
111
|
MainWidgetEntry(IWeather, WeatherWidget, "Weather", "fa5s.cloud-sun"),
|
|
108
|
-
|
|
112
|
+
# two entries sharing one interface: collect_main_widgets() matches every entry whose
|
|
113
|
+
# interface the module implements (D2), so both render as separate tabs for any IVideo
|
|
114
|
+
# module -- live view and the FITS-grab controls, fully independent widgets/state
|
|
115
|
+
# (previously one VideoWidget combining both; see
|
|
116
|
+
# specs/2026-09-01-gui-video-widget-split.md). Note: a custom `widgets:` config entry with
|
|
117
|
+
# `interface: IVideo` can only ever replace the first of these two matches (mainwindow.py's
|
|
118
|
+
# replace-in-place lookup keys on interface name, not registry position) -- a known, unused
|
|
119
|
+
# edge case, not a blocker for this pair.
|
|
120
|
+
MainWidgetEntry(IVideo, VideoWidget, "Live View", "fa5s.video"),
|
|
121
|
+
MainWidgetEntry(IVideo, VideoGrabWidget, "FITS Image", "fa5s.image", sidebar=((None, FitsHeadersWidget),)),
|
|
109
122
|
MainWidgetEntry(ISpectrograph, SpectrographWidget, "Spectrograph", "ei.graph"),
|
|
110
123
|
MainWidgetEntry(IFilters, FilterWidget, "Filter wheel", "mdi.air-filter", sidebar_preferred=True),
|
|
111
124
|
MainWidgetEntry(ITemperatures, TemperaturesWidget, "Temperatures", "mdi.thermometer", sidebar_preferred=True),
|
|
@@ -24,6 +24,11 @@ class ModeWidget(BaseWidget, Ui_ModeWidget):
|
|
|
24
24
|
self._mode_options: dict[str, list[str]] = {}
|
|
25
25
|
self._modes: dict[str, str] = {}
|
|
26
26
|
self._motion_status = MotionStatus.UNKNOWN
|
|
27
|
+
# whether self.module implements IMotion at all -- an IMode module doesn't have to be a
|
|
28
|
+
# motion device (e.g. a plain camera's fiber-hole/video-path selector), and gating the
|
|
29
|
+
# edit button on motion status for one that isn't left it permanently disabled: the
|
|
30
|
+
# IMotion state subscription below never fires, so _motion_status never leaves UNKNOWN
|
|
31
|
+
self._has_motion = False
|
|
27
32
|
self._mode_widgets: dict[str, tuple[QtWidgets.QLineEdit, QtWidgets.QToolButton]] = {}
|
|
28
33
|
|
|
29
34
|
# connect signals
|
|
@@ -42,7 +47,9 @@ class ModeWidget(BaseWidget, Ui_ModeWidget):
|
|
|
42
47
|
await self.register_event(ModeChangedEvent, self._on_mode_changed)
|
|
43
48
|
|
|
44
49
|
async def _init(self) -> None:
|
|
45
|
-
await self.comm.
|
|
50
|
+
self._has_motion = await self.comm.has_proxy(self.module, IMotion)
|
|
51
|
+
if self._has_motion:
|
|
52
|
+
await self.comm.subscribe_state(self.module, IMotion, self._on_motion_state)
|
|
46
53
|
|
|
47
54
|
# permitted methods (ACLs)
|
|
48
55
|
await self._fetch_permitted_methods()
|
|
@@ -80,7 +87,7 @@ class ModeWidget(BaseWidget, Ui_ModeWidget):
|
|
|
80
87
|
def update_gui(self) -> None:
|
|
81
88
|
self.setEnabled(True)
|
|
82
89
|
self.textStatus.setText(self._motion_status.name)
|
|
83
|
-
initialized = self._motion_status in [
|
|
90
|
+
initialized = not self._has_motion or self._motion_status in [
|
|
84
91
|
MotionStatus.SLEWING,
|
|
85
92
|
MotionStatus.TRACKING,
|
|
86
93
|
MotionStatus.IDLE,
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ui version="4.0">
|
|
3
|
+
<class>VideoGrabWidget</class>
|
|
4
|
+
<widget class="QWidget" name="VideoGrabWidget">
|
|
5
|
+
<property name="geometry">
|
|
6
|
+
<rect>
|
|
7
|
+
<x>0</x>
|
|
8
|
+
<y>0</y>
|
|
9
|
+
<width>618</width>
|
|
10
|
+
<height>530</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Form</string>
|
|
15
|
+
</property>
|
|
16
|
+
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="0,0">
|
|
17
|
+
<item>
|
|
18
|
+
<widget class="QFrame" name="frame_2">
|
|
19
|
+
<property name="frameShape">
|
|
20
|
+
<enum>QFrame::Shape::StyledPanel</enum>
|
|
21
|
+
</property>
|
|
22
|
+
<property name="frameShadow">
|
|
23
|
+
<enum>QFrame::Shadow::Raised</enum>
|
|
24
|
+
</property>
|
|
25
|
+
<layout class="QVBoxLayout" name="verticalLayout">
|
|
26
|
+
<item>
|
|
27
|
+
<widget class="QGroupBox" name="groupExposure_2">
|
|
28
|
+
<property name="title">
|
|
29
|
+
<string>Exposure</string>
|
|
30
|
+
</property>
|
|
31
|
+
<layout class="QGridLayout" name="gridLayout_5">
|
|
32
|
+
<property name="spacing">
|
|
33
|
+
<number>0</number>
|
|
34
|
+
</property>
|
|
35
|
+
<item row="0" column="0">
|
|
36
|
+
<widget class="QLabel" name="labelImageType">
|
|
37
|
+
<property name="text">
|
|
38
|
+
<string>Type:</string>
|
|
39
|
+
</property>
|
|
40
|
+
</widget>
|
|
41
|
+
</item>
|
|
42
|
+
<item row="1" column="0">
|
|
43
|
+
<widget class="QLabel" name="label_9">
|
|
44
|
+
<property name="text">
|
|
45
|
+
<string>Count:</string>
|
|
46
|
+
</property>
|
|
47
|
+
</widget>
|
|
48
|
+
</item>
|
|
49
|
+
<item row="2" column="1">
|
|
50
|
+
<widget class="QCheckBox" name="checkBroadcast">
|
|
51
|
+
<property name="text">
|
|
52
|
+
<string>Broadcast</string>
|
|
53
|
+
</property>
|
|
54
|
+
<property name="checked">
|
|
55
|
+
<bool>true</bool>
|
|
56
|
+
</property>
|
|
57
|
+
</widget>
|
|
58
|
+
</item>
|
|
59
|
+
<item row="3" column="0" colspan="2">
|
|
60
|
+
<widget class="QPushButton" name="buttonGrabImage">
|
|
61
|
+
<property name="palette">
|
|
62
|
+
<palette>
|
|
63
|
+
<active>
|
|
64
|
+
<colorrole role="Button">
|
|
65
|
+
<brush brushstyle="SolidPattern">
|
|
66
|
+
<color alpha="255">
|
|
67
|
+
<red>0</red>
|
|
68
|
+
<green>85</green>
|
|
69
|
+
<blue>0</blue>
|
|
70
|
+
</color>
|
|
71
|
+
</brush>
|
|
72
|
+
</colorrole>
|
|
73
|
+
<colorrole role="ButtonText">
|
|
74
|
+
<brush brushstyle="SolidPattern">
|
|
75
|
+
<color alpha="255">
|
|
76
|
+
<red>255</red>
|
|
77
|
+
<green>255</green>
|
|
78
|
+
<blue>255</blue>
|
|
79
|
+
</color>
|
|
80
|
+
</brush>
|
|
81
|
+
</colorrole>
|
|
82
|
+
</active>
|
|
83
|
+
<inactive>
|
|
84
|
+
<colorrole role="Button">
|
|
85
|
+
<brush brushstyle="SolidPattern">
|
|
86
|
+
<color alpha="255">
|
|
87
|
+
<red>0</red>
|
|
88
|
+
<green>85</green>
|
|
89
|
+
<blue>0</blue>
|
|
90
|
+
</color>
|
|
91
|
+
</brush>
|
|
92
|
+
</colorrole>
|
|
93
|
+
<colorrole role="ButtonText">
|
|
94
|
+
<brush brushstyle="SolidPattern">
|
|
95
|
+
<color alpha="255">
|
|
96
|
+
<red>255</red>
|
|
97
|
+
<green>255</green>
|
|
98
|
+
<blue>255</blue>
|
|
99
|
+
</color>
|
|
100
|
+
</brush>
|
|
101
|
+
</colorrole>
|
|
102
|
+
</inactive>
|
|
103
|
+
<disabled>
|
|
104
|
+
<colorrole role="Button">
|
|
105
|
+
<brush brushstyle="SolidPattern">
|
|
106
|
+
<color alpha="255">
|
|
107
|
+
<red>0</red>
|
|
108
|
+
<green>85</green>
|
|
109
|
+
<blue>0</blue>
|
|
110
|
+
</color>
|
|
111
|
+
</brush>
|
|
112
|
+
</colorrole>
|
|
113
|
+
<colorrole role="ButtonText">
|
|
114
|
+
<brush brushstyle="SolidPattern">
|
|
115
|
+
<color alpha="255">
|
|
116
|
+
<red>0</red>
|
|
117
|
+
<green>42</green>
|
|
118
|
+
<blue>0</blue>
|
|
119
|
+
</color>
|
|
120
|
+
</brush>
|
|
121
|
+
</colorrole>
|
|
122
|
+
</disabled>
|
|
123
|
+
</palette>
|
|
124
|
+
</property>
|
|
125
|
+
<property name="text">
|
|
126
|
+
<string>Grab image</string>
|
|
127
|
+
</property>
|
|
128
|
+
</widget>
|
|
129
|
+
</item>
|
|
130
|
+
<item row="1" column="1">
|
|
131
|
+
<widget class="QSpinBox" name="spinCount">
|
|
132
|
+
<property name="minimum">
|
|
133
|
+
<number>1</number>
|
|
134
|
+
</property>
|
|
135
|
+
<property name="maximum">
|
|
136
|
+
<number>9999</number>
|
|
137
|
+
</property>
|
|
138
|
+
</widget>
|
|
139
|
+
</item>
|
|
140
|
+
<item row="0" column="1">
|
|
141
|
+
<widget class="QComboBox" name="comboImageType"/>
|
|
142
|
+
</item>
|
|
143
|
+
<item row="4" column="0" colspan="2">
|
|
144
|
+
<widget class="QPushButton" name="buttonAbort">
|
|
145
|
+
<property name="palette">
|
|
146
|
+
<palette>
|
|
147
|
+
<active>
|
|
148
|
+
<colorrole role="Button">
|
|
149
|
+
<brush brushstyle="SolidPattern">
|
|
150
|
+
<color alpha="255">
|
|
151
|
+
<red>170</red>
|
|
152
|
+
<green>0</green>
|
|
153
|
+
<blue>0</blue>
|
|
154
|
+
</color>
|
|
155
|
+
</brush>
|
|
156
|
+
</colorrole>
|
|
157
|
+
<colorrole role="ButtonText">
|
|
158
|
+
<brush brushstyle="SolidPattern">
|
|
159
|
+
<color alpha="255">
|
|
160
|
+
<red>0</red>
|
|
161
|
+
<green>0</green>
|
|
162
|
+
<blue>0</blue>
|
|
163
|
+
</color>
|
|
164
|
+
</brush>
|
|
165
|
+
</colorrole>
|
|
166
|
+
</active>
|
|
167
|
+
<inactive>
|
|
168
|
+
<colorrole role="Button">
|
|
169
|
+
<brush brushstyle="SolidPattern">
|
|
170
|
+
<color alpha="255">
|
|
171
|
+
<red>170</red>
|
|
172
|
+
<green>0</green>
|
|
173
|
+
<blue>0</blue>
|
|
174
|
+
</color>
|
|
175
|
+
</brush>
|
|
176
|
+
</colorrole>
|
|
177
|
+
<colorrole role="ButtonText">
|
|
178
|
+
<brush brushstyle="SolidPattern">
|
|
179
|
+
<color alpha="255">
|
|
180
|
+
<red>0</red>
|
|
181
|
+
<green>0</green>
|
|
182
|
+
<blue>0</blue>
|
|
183
|
+
</color>
|
|
184
|
+
</brush>
|
|
185
|
+
</colorrole>
|
|
186
|
+
</inactive>
|
|
187
|
+
<disabled>
|
|
188
|
+
<colorrole role="Button">
|
|
189
|
+
<brush brushstyle="SolidPattern">
|
|
190
|
+
<color alpha="255">
|
|
191
|
+
<red>170</red>
|
|
192
|
+
<green>0</green>
|
|
193
|
+
<blue>0</blue>
|
|
194
|
+
</color>
|
|
195
|
+
</brush>
|
|
196
|
+
</colorrole>
|
|
197
|
+
<colorrole role="ButtonText">
|
|
198
|
+
<brush brushstyle="SolidPattern">
|
|
199
|
+
<color alpha="255">
|
|
200
|
+
<red>85</red>
|
|
201
|
+
<green>0</green>
|
|
202
|
+
<blue>0</blue>
|
|
203
|
+
</color>
|
|
204
|
+
</brush>
|
|
205
|
+
</colorrole>
|
|
206
|
+
</disabled>
|
|
207
|
+
</palette>
|
|
208
|
+
</property>
|
|
209
|
+
<property name="text">
|
|
210
|
+
<string>Abort sequence</string>
|
|
211
|
+
</property>
|
|
212
|
+
</widget>
|
|
213
|
+
</item>
|
|
214
|
+
</layout>
|
|
215
|
+
</widget>
|
|
216
|
+
</item>
|
|
217
|
+
<item>
|
|
218
|
+
<spacer name="verticalSpacer_2">
|
|
219
|
+
<property name="orientation">
|
|
220
|
+
<enum>Qt::Orientation::Vertical</enum>
|
|
221
|
+
</property>
|
|
222
|
+
<property name="sizeHint" stdset="0">
|
|
223
|
+
<size>
|
|
224
|
+
<width>20</width>
|
|
225
|
+
<height>40</height>
|
|
226
|
+
</size>
|
|
227
|
+
</property>
|
|
228
|
+
</spacer>
|
|
229
|
+
</item>
|
|
230
|
+
<item>
|
|
231
|
+
<widget class="QLabel" name="labelExposuresLeft">
|
|
232
|
+
<property name="text">
|
|
233
|
+
<string>IDLE</string>
|
|
234
|
+
</property>
|
|
235
|
+
<property name="alignment">
|
|
236
|
+
<set>Qt::AlignmentFlag::AlignCenter</set>
|
|
237
|
+
</property>
|
|
238
|
+
</widget>
|
|
239
|
+
</item>
|
|
240
|
+
</layout>
|
|
241
|
+
</widget>
|
|
242
|
+
</item>
|
|
243
|
+
<item>
|
|
244
|
+
<widget class="DataDisplayWidget" name="datadisplay" native="true"/>
|
|
245
|
+
</item>
|
|
246
|
+
</layout>
|
|
247
|
+
</widget>
|
|
248
|
+
<customwidgets>
|
|
249
|
+
<customwidget>
|
|
250
|
+
<class>DataDisplayWidget</class>
|
|
251
|
+
<extends>QWidget</extends>
|
|
252
|
+
<header>..datadisplaywidget</header>
|
|
253
|
+
</customwidget>
|
|
254
|
+
</customwidgets>
|
|
255
|
+
<resources/>
|
|
256
|
+
<connections/>
|
|
257
|
+
</ui>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
################################################################################
|
|
4
|
+
## Form generated from reading UI file 'videograbwidget.ui'
|
|
5
|
+
##
|
|
6
|
+
## Created by: Qt User Interface Compiler version 6.11.2
|
|
7
|
+
##
|
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
9
|
+
################################################################################
|
|
10
|
+
|
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
|
13
|
+
QSize, QTime, QUrl, Qt)
|
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
18
|
+
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QFrame,
|
|
19
|
+
QGridLayout, QGroupBox, QHBoxLayout, QLabel,
|
|
20
|
+
QPushButton, QSizePolicy, QSpacerItem, QSpinBox,
|
|
21
|
+
QVBoxLayout, QWidget)
|
|
22
|
+
|
|
23
|
+
from ..datadisplaywidget import DataDisplayWidget
|
|
24
|
+
|
|
25
|
+
class Ui_VideoGrabWidget(object):
|
|
26
|
+
def setupUi(self, VideoGrabWidget):
|
|
27
|
+
if not VideoGrabWidget.objectName():
|
|
28
|
+
VideoGrabWidget.setObjectName(u"VideoGrabWidget")
|
|
29
|
+
VideoGrabWidget.resize(618, 530)
|
|
30
|
+
self.horizontalLayout_3 = QHBoxLayout(VideoGrabWidget)
|
|
31
|
+
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
|
32
|
+
self.frame_2 = QFrame(VideoGrabWidget)
|
|
33
|
+
self.frame_2.setObjectName(u"frame_2")
|
|
34
|
+
self.frame_2.setFrameShape(QFrame.Shape.StyledPanel)
|
|
35
|
+
self.frame_2.setFrameShadow(QFrame.Shadow.Raised)
|
|
36
|
+
self.verticalLayout = QVBoxLayout(self.frame_2)
|
|
37
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
38
|
+
self.groupExposure_2 = QGroupBox(self.frame_2)
|
|
39
|
+
self.groupExposure_2.setObjectName(u"groupExposure_2")
|
|
40
|
+
self.gridLayout_5 = QGridLayout(self.groupExposure_2)
|
|
41
|
+
self.gridLayout_5.setSpacing(0)
|
|
42
|
+
self.gridLayout_5.setObjectName(u"gridLayout_5")
|
|
43
|
+
self.labelImageType = QLabel(self.groupExposure_2)
|
|
44
|
+
self.labelImageType.setObjectName(u"labelImageType")
|
|
45
|
+
|
|
46
|
+
self.gridLayout_5.addWidget(self.labelImageType, 0, 0, 1, 1)
|
|
47
|
+
|
|
48
|
+
self.label_9 = QLabel(self.groupExposure_2)
|
|
49
|
+
self.label_9.setObjectName(u"label_9")
|
|
50
|
+
|
|
51
|
+
self.gridLayout_5.addWidget(self.label_9, 1, 0, 1, 1)
|
|
52
|
+
|
|
53
|
+
self.checkBroadcast = QCheckBox(self.groupExposure_2)
|
|
54
|
+
self.checkBroadcast.setObjectName(u"checkBroadcast")
|
|
55
|
+
self.checkBroadcast.setChecked(True)
|
|
56
|
+
|
|
57
|
+
self.gridLayout_5.addWidget(self.checkBroadcast, 2, 1, 1, 1)
|
|
58
|
+
|
|
59
|
+
self.buttonGrabImage = QPushButton(self.groupExposure_2)
|
|
60
|
+
self.buttonGrabImage.setObjectName(u"buttonGrabImage")
|
|
61
|
+
palette = QPalette()
|
|
62
|
+
brush = QBrush(QColor(0, 85, 0, 255))
|
|
63
|
+
brush.setStyle(Qt.BrushStyle.SolidPattern)
|
|
64
|
+
palette.setBrush(QPalette.ColorGroup.Active, QPalette.ColorRole.Button, brush)
|
|
65
|
+
brush1 = QBrush(QColor(255, 255, 255, 255))
|
|
66
|
+
brush1.setStyle(Qt.BrushStyle.SolidPattern)
|
|
67
|
+
palette.setBrush(QPalette.ColorGroup.Active, QPalette.ColorRole.ButtonText, brush1)
|
|
68
|
+
palette.setBrush(QPalette.ColorGroup.Inactive, QPalette.ColorRole.Button, brush)
|
|
69
|
+
palette.setBrush(QPalette.ColorGroup.Inactive, QPalette.ColorRole.ButtonText, brush1)
|
|
70
|
+
palette.setBrush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Button, brush)
|
|
71
|
+
brush2 = QBrush(QColor(0, 42, 0, 255))
|
|
72
|
+
brush2.setStyle(Qt.BrushStyle.SolidPattern)
|
|
73
|
+
palette.setBrush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, brush2)
|
|
74
|
+
self.buttonGrabImage.setPalette(palette)
|
|
75
|
+
|
|
76
|
+
self.gridLayout_5.addWidget(self.buttonGrabImage, 3, 0, 1, 2)
|
|
77
|
+
|
|
78
|
+
self.spinCount = QSpinBox(self.groupExposure_2)
|
|
79
|
+
self.spinCount.setObjectName(u"spinCount")
|
|
80
|
+
self.spinCount.setMinimum(1)
|
|
81
|
+
self.spinCount.setMaximum(9999)
|
|
82
|
+
|
|
83
|
+
self.gridLayout_5.addWidget(self.spinCount, 1, 1, 1, 1)
|
|
84
|
+
|
|
85
|
+
self.comboImageType = QComboBox(self.groupExposure_2)
|
|
86
|
+
self.comboImageType.setObjectName(u"comboImageType")
|
|
87
|
+
|
|
88
|
+
self.gridLayout_5.addWidget(self.comboImageType, 0, 1, 1, 1)
|
|
89
|
+
|
|
90
|
+
self.buttonAbort = QPushButton(self.groupExposure_2)
|
|
91
|
+
self.buttonAbort.setObjectName(u"buttonAbort")
|
|
92
|
+
palette1 = QPalette()
|
|
93
|
+
brush3 = QBrush(QColor(170, 0, 0, 255))
|
|
94
|
+
brush3.setStyle(Qt.BrushStyle.SolidPattern)
|
|
95
|
+
palette1.setBrush(QPalette.ColorGroup.Active, QPalette.ColorRole.Button, brush3)
|
|
96
|
+
brush4 = QBrush(QColor(0, 0, 0, 255))
|
|
97
|
+
brush4.setStyle(Qt.BrushStyle.SolidPattern)
|
|
98
|
+
palette1.setBrush(QPalette.ColorGroup.Active, QPalette.ColorRole.ButtonText, brush4)
|
|
99
|
+
palette1.setBrush(QPalette.ColorGroup.Inactive, QPalette.ColorRole.Button, brush3)
|
|
100
|
+
palette1.setBrush(QPalette.ColorGroup.Inactive, QPalette.ColorRole.ButtonText, brush4)
|
|
101
|
+
palette1.setBrush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Button, brush3)
|
|
102
|
+
brush5 = QBrush(QColor(85, 0, 0, 255))
|
|
103
|
+
brush5.setStyle(Qt.BrushStyle.SolidPattern)
|
|
104
|
+
palette1.setBrush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText, brush5)
|
|
105
|
+
self.buttonAbort.setPalette(palette1)
|
|
106
|
+
|
|
107
|
+
self.gridLayout_5.addWidget(self.buttonAbort, 4, 0, 1, 2)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
self.verticalLayout.addWidget(self.groupExposure_2)
|
|
111
|
+
|
|
112
|
+
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
|
113
|
+
|
|
114
|
+
self.verticalLayout.addItem(self.verticalSpacer_2)
|
|
115
|
+
|
|
116
|
+
self.labelExposuresLeft = QLabel(self.frame_2)
|
|
117
|
+
self.labelExposuresLeft.setObjectName(u"labelExposuresLeft")
|
|
118
|
+
self.labelExposuresLeft.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
119
|
+
|
|
120
|
+
self.verticalLayout.addWidget(self.labelExposuresLeft)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
self.horizontalLayout_3.addWidget(self.frame_2)
|
|
124
|
+
|
|
125
|
+
self.datadisplay = DataDisplayWidget(VideoGrabWidget)
|
|
126
|
+
self.datadisplay.setObjectName(u"datadisplay")
|
|
127
|
+
|
|
128
|
+
self.horizontalLayout_3.addWidget(self.datadisplay)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
self.retranslateUi(VideoGrabWidget)
|
|
132
|
+
|
|
133
|
+
QMetaObject.connectSlotsByName(VideoGrabWidget)
|
|
134
|
+
# setupUi
|
|
135
|
+
|
|
136
|
+
def retranslateUi(self, VideoGrabWidget):
|
|
137
|
+
VideoGrabWidget.setWindowTitle(QCoreApplication.translate("VideoGrabWidget", u"Form", None))
|
|
138
|
+
self.groupExposure_2.setTitle(QCoreApplication.translate("VideoGrabWidget", u"Exposure", None))
|
|
139
|
+
self.labelImageType.setText(QCoreApplication.translate("VideoGrabWidget", u"Type:", None))
|
|
140
|
+
self.label_9.setText(QCoreApplication.translate("VideoGrabWidget", u"Count:", None))
|
|
141
|
+
self.checkBroadcast.setText(QCoreApplication.translate("VideoGrabWidget", u"Broadcast", None))
|
|
142
|
+
self.buttonGrabImage.setText(QCoreApplication.translate("VideoGrabWidget", u"Grab image", None))
|
|
143
|
+
self.buttonAbort.setText(QCoreApplication.translate("VideoGrabWidget", u"Abort sequence", None))
|
|
144
|
+
self.labelExposuresLeft.setText(QCoreApplication.translate("VideoGrabWidget", u"IDLE", None))
|
|
145
|
+
# retranslateUi
|
|
146
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ui version="4.0">
|
|
3
|
+
<class>VideoWidget</class>
|
|
4
|
+
<widget class="QWidget" name="VideoWidget">
|
|
5
|
+
<property name="geometry">
|
|
6
|
+
<rect>
|
|
7
|
+
<x>0</x>
|
|
8
|
+
<y>0</y>
|
|
9
|
+
<width>618</width>
|
|
10
|
+
<height>530</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Form</string>
|
|
15
|
+
</property>
|
|
16
|
+
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
|
|
17
|
+
<item>
|
|
18
|
+
<widget class="QFrame" name="frame">
|
|
19
|
+
<property name="frameShape">
|
|
20
|
+
<enum>QFrame::Shape::StyledPanel</enum>
|
|
21
|
+
</property>
|
|
22
|
+
<property name="frameShadow">
|
|
23
|
+
<enum>QFrame::Shadow::Raised</enum>
|
|
24
|
+
</property>
|
|
25
|
+
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
26
|
+
<item>
|
|
27
|
+
<widget class="QGroupBox" name="groupExposure">
|
|
28
|
+
<property name="title">
|
|
29
|
+
<string/>
|
|
30
|
+
</property>
|
|
31
|
+
<layout class="QFormLayout" name="formLayout">
|
|
32
|
+
<item row="0" column="1">
|
|
33
|
+
<widget class="QDoubleSpinBox" name="spinExpTime">
|
|
34
|
+
<property name="suffix">
|
|
35
|
+
<string> s</string>
|
|
36
|
+
</property>
|
|
37
|
+
<property name="decimals">
|
|
38
|
+
<number>6</number>
|
|
39
|
+
</property>
|
|
40
|
+
<property name="maximum">
|
|
41
|
+
<double>999.000000000000000</double>
|
|
42
|
+
</property>
|
|
43
|
+
<property name="value">
|
|
44
|
+
<double>1.000000000000000</double>
|
|
45
|
+
</property>
|
|
46
|
+
</widget>
|
|
47
|
+
</item>
|
|
48
|
+
<item row="0" column="0">
|
|
49
|
+
<widget class="QLabel" name="labelExpTime">
|
|
50
|
+
<property name="text">
|
|
51
|
+
<string>ExpTime:</string>
|
|
52
|
+
</property>
|
|
53
|
+
</widget>
|
|
54
|
+
</item>
|
|
55
|
+
</layout>
|
|
56
|
+
</widget>
|
|
57
|
+
</item>
|
|
58
|
+
<item>
|
|
59
|
+
<widget class="QGroupBox" name="groupGain">
|
|
60
|
+
<property name="title">
|
|
61
|
+
<string/>
|
|
62
|
+
</property>
|
|
63
|
+
<layout class="QGridLayout" name="gridLayout">
|
|
64
|
+
<item row="0" column="0">
|
|
65
|
+
<widget class="QLabel" name="label_11">
|
|
66
|
+
<property name="text">
|
|
67
|
+
<string>Gain:</string>
|
|
68
|
+
</property>
|
|
69
|
+
</widget>
|
|
70
|
+
</item>
|
|
71
|
+
<item row="0" column="1">
|
|
72
|
+
<widget class="QDoubleSpinBox" name="spinGain"/>
|
|
73
|
+
</item>
|
|
74
|
+
</layout>
|
|
75
|
+
</widget>
|
|
76
|
+
</item>
|
|
77
|
+
<item>
|
|
78
|
+
<spacer name="verticalSpacer">
|
|
79
|
+
<property name="orientation">
|
|
80
|
+
<enum>Qt::Orientation::Vertical</enum>
|
|
81
|
+
</property>
|
|
82
|
+
<property name="sizeHint" stdset="0">
|
|
83
|
+
<size>
|
|
84
|
+
<width>20</width>
|
|
85
|
+
<height>340</height>
|
|
86
|
+
</size>
|
|
87
|
+
</property>
|
|
88
|
+
</spacer>
|
|
89
|
+
</item>
|
|
90
|
+
</layout>
|
|
91
|
+
</widget>
|
|
92
|
+
</item>
|
|
93
|
+
<item>
|
|
94
|
+
<widget class="QWidget" name="frameLiveView" native="true">
|
|
95
|
+
<layout class="QVBoxLayout" name="verticalLayout_4"/>
|
|
96
|
+
</widget>
|
|
97
|
+
</item>
|
|
98
|
+
</layout>
|
|
99
|
+
</widget>
|
|
100
|
+
<resources/>
|
|
101
|
+
<connections/>
|
|
102
|
+
</ui>
|