Skip to content

Commit a9ca29c

Browse files
Try this
1 parent f83c8ae commit a9ca29c

File tree

5 files changed

+53
-26
lines changed

5 files changed

+53
-26
lines changed

lock.json

+12-8
Large diffs are not rendered by default.

requirements/requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ dvc-task==0.4.0
6868
dvc==3.51.2
6969
entrypoints==0.4
7070
executing==2.0.1
71-
fastjsonschema==2.19.1
71+
fastjsonschema==2.20.0
7272
fawltydeps==0.15.0
7373
filelock==3.15.1
7474
flatten-dict==0.4.2
@@ -207,6 +207,7 @@ pyside6==6.7.1
207207
pytest-cov==4.1.0
208208
pytest-custom-exit-code==0.3.0
209209
pytest-github-actions-annotate-failures==0.2.0
210+
pytest-qt==4.4.0
210211
pytest==8.0.0
211212
python-dateutil==2.9.0.post0
212213
pytz==2024.1

src/boilerdaq/daq.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
mkQApp,
2525
setConfigOptions,
2626
)
27-
from PySide6.QtCore import QTimer
27+
from PySide6.QtCore import Qt, QTimer, Signal
28+
from PySide6.QtGui import QKeyEvent
2829
from pyvisa import ResourceManager, VisaIOError
2930
from pyvisa.resources import MessageBasedResource
3031
from simple_pid import PID
@@ -741,6 +742,17 @@ def write(self):
741742
csv_writer.writerow(to_write)
742743

743744

745+
class GraphicsLayoutWidgetWithKeySignal(GraphicsLayoutWidget):
746+
"""Emit key signals on `key_signal`."""
747+
748+
key_signal = Signal(QKeyEvent)
749+
750+
def keyPressEvent(self, ev: QKeyEvent): # noqa: N802
751+
"""Handle keypresses."""
752+
super().keyPressEvent(ev)
753+
self.key_signal.emit(ev)
754+
755+
744756
class Plotter:
745757
"""A plotter for data.
746758
@@ -764,7 +776,9 @@ class Plotter:
764776
"""
765777

766778
def __init__(self, title: str, results: list[Result], row: int = 0, col: int = 0):
767-
self.window = GraphicsLayoutWidget()
779+
self.window = GraphicsLayoutWidgetWithKeySignal()
780+
self.app = mkQApp()
781+
self.window.key_signal.connect(self.keyPressEvent)
768782
self.all_results: list[Result] = []
769783
self.all_curves: list[PlotCurveItem] = []
770784
self.all_histories: list[deque[float]] = []
@@ -776,6 +790,12 @@ def __init__(self, title: str, results: list[Result], row: int = 0, col: int = 0
776790
)
777791
self.add(title, results, row, col)
778792

793+
def keyPressEvent(self, ev: QKeyEvent): # noqa: N802
794+
"""Handle quit events and propagate keypresses to image views."""
795+
if ev.key() in (Qt.Key.Key_Escape, Qt.Key.Key_Q, Qt.Key.Key_Enter):
796+
self.app.closeAllWindows()
797+
ev.accept()
798+
779799
def add(self, title: str, results: list[Result], row: int, col: int):
780800
"""Plot results to a new pane in the plot window.
781801
@@ -831,7 +851,6 @@ class Looper:
831851
def __init__(
832852
self, writer: Writer, plotter: Plotter, controller: Controller | None = None
833853
):
834-
self.app = mkQApp()
835854
self.writer = writer
836855
self.plotter = plotter
837856
self.controller: Controller = controller or None # type: ignore
@@ -845,8 +864,8 @@ def start(self):
845864
timer.timeout.connect(self.plot_control if self.controller else self.plot)
846865
timer.start(POLLING_INTERVAL)
847866
self.plotter.window.show()
848-
self.app.exec()
849-
self.app.quit()
867+
self.plotter.app.exec()
868+
self.plotter.app.quit()
850869
if self.controller:
851870
self.controller.close()
852871

tests/boilerdaq_tests/conftest.py

+13-11
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@
88
from boilercore import WarningFilter, filter_certain_warnings
99
from boilercore.paths import get_module_rel, walk_modules
1010
from boilercore.testing import get_session_path
11-
from debugpy import is_client_connected
12-
from PySide6.QtCore import QTimer
13-
from PySide6.QtWidgets import QApplication
11+
from PySide6.QtCore import Qt, QTimer
12+
from PySide6.QtTest import QTest
1413

1514
import boilerdaq
1615
from boilerdaq import INSTRUMENT
1716
from boilerdaq.daq import Looper, open_instrument
1817

19-
DEBUG = is_client_connected()
20-
21-
2218
STAGES_DIR = Path("src") / "boilerdaq" / "stages"
2319
STAGES: list[Any] = []
2420
for module in (f"boilerdaq.{module}" for module in walk_modules(STAGES_DIR)):
@@ -48,7 +44,7 @@ def _disable_power_supply():
4844

4945

5046
# Can't be session scope
51-
@pytest.fixture(autouse=True)
47+
@pytest.fixture()
5248
def _filter_certain_warnings():
5349
"""Filter certain warnings."""
5450
filter_certain_warnings([
@@ -61,11 +57,17 @@ def _filter_certain_warnings():
6157

6258

6359
@pytest.fixture(params=STAGES)
64-
def looper(request: pytest.FixtureRequest):
60+
def looper(qtbot, request: pytest.FixtureRequest):
6561
"""Test example procedures."""
6662
module = import_module(request.param)
6763
looper: Looper = getattr(module, "looper", lambda: None)() or module.main()
68-
if not DEBUG:
69-
app: QApplication = looper.app
70-
QTimer.singleShot(2000, app.closeAllWindows)
64+
QTimer.singleShot(
65+
2000,
66+
lambda: qtbot.keyEvent(
67+
QTest.KeyAction.Press,
68+
looper.plotter.window,
69+
Qt.Key.Key_Escape,
70+
Qt.KeyboardModifier.NoModifier,
71+
),
72+
)
7173
return looper

tests/pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ version = "0.0.0"
88
description = "Tests."
99
dependencies = [
1010
# ? Core testing
11-
"debugpy==1.8.1",
1211
"pytest-cov==4.1.0",
1312
"pytest-custom-exit-code==0.3.0",
1413
"pytest-github-actions-annotate-failures==0.2.0",
1514
"pytest==8.0.0",
1615
# ? Other testing
1716
# ? Wheels are missing on Linux for PySide6, `uv` doesn't like it
1817
"pyside6==6.7.1 ; sys_platform != 'linux'",
18+
"pytest-qt==4.4.0",
1919
]
2020

2121
[tool.fawltydeps]
@@ -34,4 +34,5 @@ ignore_unused = [
3434
"pytest-custom-exit-code",
3535
"pytest-github-actions-annotate-failures",
3636
"pytest",
37+
"pytest-qt",
3738
]

0 commit comments

Comments
 (0)