mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-04-15 13:10:54 +02:00
Compare commits
1 Commits
v2.30.6
...
feature/fi
| Author | SHA1 | Date | |
|---|---|---|---|
| 161c1570bd |
29
CHANGELOG.md
29
CHANGELOG.md
@@ -1,35 +1,6 @@
|
||||
# CHANGELOG
|
||||
|
||||
|
||||
## v2.30.6 (2025-07-26)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **waveform**: Autorange is applied with 150ms delay after curve is added
|
||||
([`61e5bde`](https://github.com/bec-project/bec_widgets/commit/61e5bde15f0e1ebe185ddbe81cd71ad581ae6009))
|
||||
|
||||
|
||||
## v2.30.5 (2025-07-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **positioner-box**: Test to fix handling of none integer values for precision
|
||||
([`b718b43`](https://github.com/bec-project/bec_widgets/commit/b718b438bacff6eb6cd6015f1a67dcf75c05dce4))
|
||||
|
||||
### Refactoring
|
||||
|
||||
- **positioner-box**: Cleanup, accept float precision
|
||||
([`4d5df96`](https://github.com/bec-project/bec_widgets/commit/4d5df9608a9438b9f6d7508c323eb3772e53f37d))
|
||||
|
||||
|
||||
## v2.30.4 (2025-07-25)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **cli**: Remove stderr from cli output when not using rpc
|
||||
([`b4e0664`](https://github.com/bec-project/bec_widgets/commit/b4e0664011682cae9966aa2632210a6b60e11714))
|
||||
|
||||
|
||||
## v2.30.3 (2025-07-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -37,6 +37,7 @@ _Widgets = {
|
||||
"DeviceBrowser": "DeviceBrowser",
|
||||
"DeviceComboBox": "DeviceComboBox",
|
||||
"DeviceLineEdit": "DeviceLineEdit",
|
||||
"FileBrowser": "FileBrowser",
|
||||
"Heatmap": "Heatmap",
|
||||
"Image": "Image",
|
||||
"LogPanel": "LogPanel",
|
||||
@@ -1183,6 +1184,16 @@ class EllipticalROI(RPCBase):
|
||||
"""
|
||||
|
||||
|
||||
class FileBrowser(RPCBase):
|
||||
"""A simple file browser widget."""
|
||||
|
||||
@rpc_call
|
||||
def remove(self):
|
||||
"""
|
||||
Cleanup the BECConnector
|
||||
"""
|
||||
|
||||
|
||||
class Heatmap(RPCBase):
|
||||
"""Heatmap widget for visualizing 2d grid data with color mapping for the z-axis."""
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ def _filter_output(output: str) -> str:
|
||||
|
||||
|
||||
def _get_output(process, logger) -> None:
|
||||
log_func = {process.stdout: logger.debug, process.stderr: logger.info}
|
||||
log_func = {process.stdout: logger.debug, process.stderr: logger.error}
|
||||
stream_buffer = {process.stdout: [], process.stderr: []}
|
||||
try:
|
||||
os.set_blocking(process.stdout.fileno(), False)
|
||||
|
||||
@@ -138,11 +138,7 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
||||
signals = msg_content.get("signals", {})
|
||||
# pylint: disable=protected-access
|
||||
hinted_signals = self.dev[device]._hints
|
||||
precision = getattr(self.dev[device], "precision", 8)
|
||||
try:
|
||||
precision = int(precision)
|
||||
except (TypeError, ValueError):
|
||||
precision = int(8)
|
||||
precision = self.dev[device].precision
|
||||
|
||||
spinner = ui_components["spinner"]
|
||||
position_indicator = ui_components["position_indicator"]
|
||||
@@ -182,13 +178,11 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
||||
spinner.setVisible(False)
|
||||
|
||||
if readback_val is not None:
|
||||
text = f"{readback_val:.{precision}f}"
|
||||
readback.setText(text)
|
||||
readback.setText(f"{readback_val:.{precision}f}")
|
||||
position_emit(readback_val)
|
||||
|
||||
if setpoint_val is not None:
|
||||
text = f"{setpoint_val:.{precision}f}"
|
||||
setpoint.setText(text)
|
||||
setpoint.setText(f"{setpoint_val:.{precision}f}")
|
||||
|
||||
limits = self.dev[device].limits
|
||||
limit_update(limits)
|
||||
@@ -211,13 +205,10 @@ class PositionerBoxBase(BECWidget, CompactPopupWidget):
|
||||
ui["readback"].setToolTip(f"{device} readback")
|
||||
ui["setpoint"].setToolTip(f"{device} setpoint")
|
||||
ui["step_size"].setToolTip(f"Step size for {device}")
|
||||
precision = getattr(self.dev[device], "precision", 8)
|
||||
try:
|
||||
precision = int(precision)
|
||||
except (TypeError, ValueError):
|
||||
precision = int(8)
|
||||
ui["step_size"].setDecimals(precision)
|
||||
ui["step_size"].setValue(10**-precision * 10)
|
||||
precision = self.dev[device].precision
|
||||
if precision is not None:
|
||||
ui["step_size"].setDecimals(precision)
|
||||
ui["step_size"].setValue(10**-precision * 10)
|
||||
|
||||
def _swap_readback_signal_connection(self, slot, old_device, new_device):
|
||||
self.bec_dispatcher.disconnect_slot(slot, MessageEndpoints.device_readback(old_device))
|
||||
|
||||
@@ -45,12 +45,7 @@ class PositionerGroupBox(QGroupBox):
|
||||
|
||||
def _on_position_update(self, pos: float):
|
||||
self.position_update.emit(pos)
|
||||
precision = getattr(self.widget.dev[self.widget.device], "precision", 8)
|
||||
try:
|
||||
precision = int(precision)
|
||||
except (TypeError, ValueError):
|
||||
precision = int(8)
|
||||
self.widget.label = f"{pos:.{precision}f}"
|
||||
self.widget.label = f"%.{self.widget.dev[self.widget.device].precision}f" % pos
|
||||
|
||||
def close(self):
|
||||
self.widget.close()
|
||||
|
||||
@@ -908,10 +908,6 @@ class Waveform(PlotBase):
|
||||
self.roi_enable.emit(True) # Enable the ROI toolbar action
|
||||
self.request_dap() # Request DAP update directly without blocking proxy
|
||||
|
||||
QTimer.singleShot(
|
||||
150, self.auto_range
|
||||
) # autorange with a delay to ensure the plot is updated
|
||||
|
||||
return curve
|
||||
|
||||
def _add_curve_object(self, name: str, config: CurveConfig) -> Curve:
|
||||
|
||||
298
bec_widgets/widgets/utility/file_browser/file_browser.py
Normal file
298
bec_widgets/widgets/utility/file_browser/file_browser.py
Normal file
@@ -0,0 +1,298 @@
|
||||
from PySide6.QtWidgets import QVBoxLayout
|
||||
from qtpy.QtCore import QDir
|
||||
from qtpy.QtWidgets import QApplication, QFileSystemModel, QHeaderView, QTreeView, QWidget
|
||||
|
||||
from bec_widgets.utils.bec_widget import BECWidget
|
||||
from bec_widgets.utils.error_popups import SafeProperty
|
||||
from bec_widgets.utils.toolbars.actions import MaterialIconAction
|
||||
from bec_widgets.utils.toolbars.bundles import ToolbarBundle
|
||||
from bec_widgets.utils.toolbars.toolbar import ModularToolBar
|
||||
|
||||
|
||||
class FileBrowser(BECWidget, QWidget):
|
||||
"""
|
||||
A simple file browser widget.
|
||||
"""
|
||||
|
||||
PLUGIN = True
|
||||
ICON_NAME = "folder_open"
|
||||
|
||||
def __init__(self, parent=None, config=None, client=None, gui_id=None, **kwargs):
|
||||
super().__init__(parent=parent, client=client, gui_id=gui_id, config=config, **kwargs)
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.tree = QTreeView(self)
|
||||
|
||||
self.model = QFileSystemModel()
|
||||
self.tree.setModel(self.model)
|
||||
self.tree.setRootIndex(self.model.index(QDir.rootPath()))
|
||||
self.model.setRootPath(QDir.rootPath())
|
||||
|
||||
self._allow_changing_root = True
|
||||
self._original_root_path = QDir.rootPath()
|
||||
|
||||
self.toolbar = ModularToolBar(parent=self, orientation="horizontal")
|
||||
|
||||
self._go_back_action = MaterialIconAction("arrow_back", "Go Back", parent=self)
|
||||
self.toolbar.components.add_safe("go_back", self._go_back_action)
|
||||
self.toolbar.components.add_safe(
|
||||
"refresh", MaterialIconAction("refresh", "Refresh", parent=self)
|
||||
)
|
||||
self.toolbar.components.add_safe(
|
||||
"open", MaterialIconAction("folder_open", "Open File", parent=self)
|
||||
)
|
||||
bundle = ToolbarBundle("file_io", self.toolbar.components)
|
||||
bundle.add_action("go_back")
|
||||
bundle.add_action("refresh")
|
||||
bundle.add_action("open")
|
||||
self.toolbar.add_bundle(bundle)
|
||||
|
||||
self.toolbar.show_bundles(["file_io"])
|
||||
|
||||
layout.addWidget(self.toolbar)
|
||||
layout.addWidget(self.tree)
|
||||
self.setLayout(layout)
|
||||
|
||||
self._show_hidden_files = False
|
||||
self._go_back_action.action.setEnabled(False)
|
||||
self._go_back_action.action.triggered.connect(self._on_go_back)
|
||||
|
||||
self.tree.setSelectionMode(QTreeView.SelectionMode.SingleSelection)
|
||||
self.tree.doubleClicked.connect(self._on_double_click)
|
||||
|
||||
def _on_double_click(self, index):
|
||||
"""
|
||||
Handle double-click events on the file browser.
|
||||
Opens the selected file or directory.
|
||||
"""
|
||||
if not index.isValid():
|
||||
return
|
||||
|
||||
path = self.model.filePath(index)
|
||||
if self.model.isDir(index) and self._allow_changing_root:
|
||||
self.tree.setRootIndex(index)
|
||||
if path != self._original_root_path:
|
||||
self._go_back_action.action.setEnabled(True)
|
||||
else:
|
||||
self._go_back_action.action.setEnabled(False)
|
||||
return
|
||||
print(f"Opening file: {path}")
|
||||
|
||||
def _on_go_back(self):
|
||||
"""
|
||||
Handle the go back action.
|
||||
Navigates to the previous directory in the file browser.
|
||||
"""
|
||||
if self._allow_changing_root and self.tree.rootIndex().isValid():
|
||||
parent_index = self.tree.rootIndex().parent()
|
||||
if parent_index.isValid():
|
||||
self.tree.setRootIndex(parent_index)
|
||||
if parent_index != self.model.index(self._original_root_path):
|
||||
self._go_back_action.action.setEnabled(True)
|
||||
else:
|
||||
self._go_back_action.action.setEnabled(False)
|
||||
|
||||
@SafeProperty(bool)
|
||||
def show_toolbar(self):
|
||||
"""
|
||||
Get whether the toolbar is shown in the file browser.
|
||||
"""
|
||||
return not self.toolbar.isHidden()
|
||||
|
||||
@show_toolbar.setter
|
||||
def show_toolbar(self, show: bool):
|
||||
"""
|
||||
Set whether the toolbar is shown in the file browser.
|
||||
"""
|
||||
self.toolbar.setVisible(show)
|
||||
|
||||
@SafeProperty(bool)
|
||||
def show_hidden_files(self):
|
||||
"""
|
||||
Get whether hidden files are shown in the file browser.
|
||||
"""
|
||||
return self._show_hidden_files
|
||||
|
||||
@show_hidden_files.setter
|
||||
def show_hidden_files(self, show: bool):
|
||||
"""
|
||||
Set whether hidden files are shown in the file browser.
|
||||
"""
|
||||
self._show_hidden_files = show
|
||||
if show:
|
||||
self.model.setFilter(
|
||||
QDir.Filter.AllDirs
|
||||
| QDir.Filter.Files
|
||||
| QDir.Filter.NoDotAndDotDot
|
||||
| QDir.Filter.Hidden
|
||||
)
|
||||
else:
|
||||
self.model.setFilter(
|
||||
QDir.Filter.AllDirs | QDir.Filter.Files | QDir.Filter.NoDotAndDotDot
|
||||
)
|
||||
self.tree.setRootIndex(self.model.index(self.model.rootPath()))
|
||||
|
||||
@SafeProperty(bool)
|
||||
def allow_changing_root(self):
|
||||
"""
|
||||
Get whether changing the root path is allowed.
|
||||
"""
|
||||
return self._allow_changing_root
|
||||
|
||||
@allow_changing_root.setter
|
||||
def allow_changing_root(self, allow: bool):
|
||||
"""
|
||||
Set whether changing the root path is allowed.
|
||||
"""
|
||||
self._allow_changing_root = allow
|
||||
|
||||
@SafeProperty(bool)
|
||||
def show_file_size(self):
|
||||
"""
|
||||
Get whether the file size is shown in the file browser.
|
||||
"""
|
||||
index = self._section_index("Size")
|
||||
return not self.tree.header().isSectionHidden(index)
|
||||
|
||||
@show_file_size.setter
|
||||
def show_file_size(self, show: bool):
|
||||
"""
|
||||
Set whether the file size is shown in the file browser.
|
||||
"""
|
||||
index = self._section_index("Size")
|
||||
self.tree.header().setSectionHidden(index, not show)
|
||||
self.tree.header().repaint()
|
||||
|
||||
@SafeProperty(bool)
|
||||
def show_file_kind(self):
|
||||
"""
|
||||
Get whether the file kind is shown in the file browser.
|
||||
"""
|
||||
index = self._section_index("Kind")
|
||||
return not self.tree.header().isSectionHidden(index)
|
||||
|
||||
@show_file_kind.setter
|
||||
def show_file_kind(self, show: bool):
|
||||
"""
|
||||
Set whether the file kind is shown in the file browser.
|
||||
"""
|
||||
index = self._section_index("Kind")
|
||||
self.tree.header().setSectionHidden(index, not show)
|
||||
self.tree.setRootIndex(self.model.index(self.model.rootPath()))
|
||||
|
||||
@SafeProperty(bool)
|
||||
def show_file_timestamp(self):
|
||||
"""
|
||||
Get whether the file timestamp is shown in the file browser.
|
||||
"""
|
||||
index = self._section_index("Date Modified")
|
||||
return not self.tree.header().isSectionHidden(index)
|
||||
|
||||
@show_file_timestamp.setter
|
||||
def show_file_timestamp(self, show: bool):
|
||||
"""
|
||||
Set whether the file timestamp is shown in the file browser.
|
||||
"""
|
||||
index = self._section_index("Date Modified")
|
||||
self.tree.header().setSectionHidden(index, not show)
|
||||
self.tree.header().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
|
||||
self.tree.setRootIndex(self.model.index(self.model.rootPath()))
|
||||
|
||||
@SafeProperty(str)
|
||||
def root_path(self):
|
||||
"""
|
||||
Get the root path of the file browser.
|
||||
"""
|
||||
return self.model.rootPath()
|
||||
|
||||
@root_path.setter
|
||||
def root_path(self, path: str):
|
||||
"""
|
||||
Set the root path of the file browser.
|
||||
"""
|
||||
self.model.setRootPath(path)
|
||||
self.tree.setRootIndex(self.model.index(path))
|
||||
self._original_root_path = path
|
||||
|
||||
@SafeProperty(bool)
|
||||
def show_header(self):
|
||||
"""
|
||||
Get whether the header is shown in the file browser.
|
||||
"""
|
||||
return not self.tree.header().isHidden()
|
||||
|
||||
@show_header.setter
|
||||
def show_header(self, show: bool):
|
||||
"""
|
||||
Set whether the header is shown in the file browser.
|
||||
"""
|
||||
self.tree.setHeaderHidden(not show)
|
||||
self.tree.setRootIndex(self.model.index(self.model.rootPath()))
|
||||
|
||||
def _section_index(self, label: str) -> int:
|
||||
header = self.tree.header()
|
||||
model = self.tree.model()
|
||||
for i in range(model.columnCount()):
|
||||
if model.headerData(i, header.orientation()) == label:
|
||||
return i
|
||||
print(f"Section '{label}' not found in header.")
|
||||
return -1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
file_browser = FileBrowser()
|
||||
file_browser.root_path = "/Users/wakonig_k/software/work/bec-widgets/bec_widgets"
|
||||
file_browser.show_file_size = False
|
||||
file_browser.show_file_kind = False
|
||||
file_browser.show_file_timestamp = False
|
||||
file_browser.show_hidden_files = True
|
||||
file_browser.show_header = False
|
||||
file_browser.show()
|
||||
sys.exit(app.exec_())
|
||||
# from qtpy.QtCore import Qt
|
||||
# from qtpy.QtWidgets import QDockWidget, QFileSystemModel, QTreeView
|
||||
|
||||
# class ExplorerDock(QWidget):
|
||||
# def __init__(self, cpath, themes):
|
||||
# super().__init__()
|
||||
# self._themes = themes
|
||||
# self.setWindowTitle("Explorer")
|
||||
# self.tree = QTreeView(self)
|
||||
# self.model = QFileSystemModel()
|
||||
# self.tree.setModel(self.model)
|
||||
# self.tree.setRootIndex(self.model.index(cpath))
|
||||
# self.model.setRootPath(cpath)
|
||||
|
||||
# layout = QVBoxLayout(self)
|
||||
# layout.setContentsMargins(0, 0, 0, 0)
|
||||
# layout.addWidget(self.tree)
|
||||
|
||||
# app = QApplication([])
|
||||
# explorer = ExplorerDock(
|
||||
# cpath="/Users/wakonig_k/software/work/csaxs_bec/csaxs_bec", themes={"sidebar_bg": "#2E2E2E"}
|
||||
# )
|
||||
# explorer.show()
|
||||
# app.exec_()
|
||||
|
||||
|
||||
# # self.dock = QDockWidget("Explorer", self)
|
||||
# # self.dock.setMinimumWidth(200)
|
||||
# # self.dock.visibilityChanged.connect(
|
||||
# # lambda visible: self.onExplorerDockVisibilityChanged(visible)
|
||||
# # )
|
||||
# # self.dock.setAllowedAreas(Qt.DockWidgetArea.AllDockWidgetAreas)
|
||||
# # tree_view = QTreeView()
|
||||
|
||||
# # self.model = QFileSystemModel()
|
||||
# # bg = self._themes["sidebar_bg"]
|
||||
# # tree_view.setStyleSheet(
|
||||
# # f"QTreeView {{background-color: {bg}; color: white; border: none; }}"
|
||||
# # )
|
||||
# # tree_view.setModel(self.model)
|
||||
# # tree_view.setRootIndex(self.model.index(cpath))
|
||||
# # self.model.setRootPath(cpath)
|
||||
@@ -0,0 +1 @@
|
||||
{'files': ['file_browser.py']}
|
||||
@@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
from qtpy.QtDesigner import QDesignerCustomWidgetInterface
|
||||
|
||||
from bec_widgets.utils.bec_designer import designer_material_icon
|
||||
from bec_widgets.widgets.utility.file_browser.file_browser import FileBrowser
|
||||
|
||||
DOM_XML = """
|
||||
<ui language='c++'>
|
||||
<widget class='FileBrowser' name='file_browser'>
|
||||
</widget>
|
||||
</ui>
|
||||
"""
|
||||
|
||||
|
||||
class FileBrowserPlugin(QDesignerCustomWidgetInterface): # pragma: no cover
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._form_editor = None
|
||||
|
||||
def createWidget(self, parent):
|
||||
t = FileBrowser(parent)
|
||||
return t
|
||||
|
||||
def domXml(self):
|
||||
return DOM_XML
|
||||
|
||||
def group(self):
|
||||
return "BEC Utils"
|
||||
|
||||
def icon(self):
|
||||
return designer_material_icon(FileBrowser.ICON_NAME)
|
||||
|
||||
def includeFile(self):
|
||||
return "file_browser"
|
||||
|
||||
def initialize(self, form_editor):
|
||||
self._form_editor = form_editor
|
||||
|
||||
def isContainer(self):
|
||||
return False
|
||||
|
||||
def isInitialized(self):
|
||||
return self._form_editor is not None
|
||||
|
||||
def name(self):
|
||||
return "FileBrowser"
|
||||
|
||||
def toolTip(self):
|
||||
return ""
|
||||
|
||||
def whatsThis(self):
|
||||
return self.toolTip()
|
||||
@@ -0,0 +1,15 @@
|
||||
def main(): # pragma: no cover
|
||||
from qtpy import PYSIDE6
|
||||
|
||||
if not PYSIDE6:
|
||||
print("PYSIDE6 is not available in the environment. Cannot patch designer.")
|
||||
return
|
||||
from PySide6.QtDesigner import QPyDesignerCustomWidgetCollection
|
||||
|
||||
from bec_widgets.widgets.utility.file_browser.file_browser_plugin import FileBrowserPlugin
|
||||
|
||||
QPyDesignerCustomWidgetCollection.addCustomWidget(FileBrowserPlugin())
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
main()
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "bec_widgets"
|
||||
version = "2.30.6"
|
||||
version = "2.30.3"
|
||||
description = "BEC Widgets"
|
||||
requires-python = ">=3.10"
|
||||
classifiers = [
|
||||
|
||||
@@ -7,7 +7,6 @@ from qtpy.QtCore import Qt, QTimer
|
||||
from qtpy.QtGui import QValidator
|
||||
from qtpy.QtWidgets import QPushButton
|
||||
|
||||
from bec_widgets.tests.utils import Positioner
|
||||
from bec_widgets.widgets.control.device_control.positioner_box import (
|
||||
PositionerBox,
|
||||
PositionerControlLine,
|
||||
@@ -20,18 +19,6 @@ from .client_mocks import mocked_client
|
||||
from .conftest import create_widget
|
||||
|
||||
|
||||
class PositionerWithoutPrecision(Positioner):
|
||||
"""just placeholder for testing embedded isinstance check in DeviceCombobox"""
|
||||
|
||||
def __init__(self, precision, name="test", limits=None, read_value=1.0, enabled=True):
|
||||
super().__init__(name, limits=limits, read_value=read_value, enabled=enabled)
|
||||
self._precision = precision
|
||||
|
||||
@property
|
||||
def precision(self):
|
||||
return self._precision
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def positioner_box(qtbot, mocked_client):
|
||||
"""Fixture for PositionerBox widget"""
|
||||
@@ -178,26 +165,3 @@ def test_device_validity_check_rejects_non_positioner():
|
||||
positioner_box = mock.MagicMock(spec=PositionerBox)
|
||||
positioner_box.dev = {"test": 5.123}
|
||||
assert not PositionerBox._check_device_is_valid(positioner_box, "test")
|
||||
|
||||
|
||||
def test_positioner_box_device_without_precision(qtbot, positioner_box):
|
||||
"""Test positioner box with device without precision"""
|
||||
|
||||
for ii, mock_return in enumerate([None, 2, 2.0, True, "tmp"]):
|
||||
dev_name = f"samy_{ii}"
|
||||
device = PositionerWithoutPrecision(
|
||||
precision=mock_return, name=dev_name, limits=[-5, 5], read_value=3.0
|
||||
)
|
||||
positioner_box.bec_dispatcher.client.device_manager.add_devices(devices=[device])
|
||||
|
||||
positioner_box.device = dev_name
|
||||
|
||||
def check_title():
|
||||
return positioner_box.ui.device_box.title() == dev_name
|
||||
|
||||
qtbot.waitUntil(check_title, timeout=3000)
|
||||
if isinstance(mock_return, (int, float)):
|
||||
mock_return = int(mock_return)
|
||||
assert positioner_box.ui.step_size.value() == 10**-mock_return * 10
|
||||
else:
|
||||
assert positioner_box.ui.step_size.value() == 10**-8 * 10
|
||||
|
||||
Reference in New Issue
Block a user