Добавить общее перетаскивание графиков и независимые шкалы амплитуд
This commit is contained in:
129
python/tests/test_plot_drag_qt.py
Normal file
129
python/tests/test_plot_drag_qt.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""Shared drag gestures, with real Qt events and C math, without SETGUI imports."""
|
||||
import ctypes
|
||||
import os
|
||||
import unittest
|
||||
from dataclasses import replace
|
||||
|
||||
os.environ.setdefault('QT_QPA_PLATFORM', 'offscreen')
|
||||
try:
|
||||
from PySide6.QtCore import QEvent, QPoint, QPointF, QRectF, Qt, Signal
|
||||
from PySide6.QtGui import QMouseEvent
|
||||
from PySide6.QtTest import QTest
|
||||
from PySide6.QtWidgets import QApplication, QCheckBox, QWidget
|
||||
except ImportError:
|
||||
from PySide2.QtCore import QEvent, QPoint, QPointF, QRectF, Qt, Signal
|
||||
from PySide2.QtGui import QMouseEvent
|
||||
from PySide2.QtTest import QTest
|
||||
from PySide2.QtWidgets import QApplication, QCheckBox, QWidget
|
||||
|
||||
from protocan.plot import Bounds, Marker, Markers, PlotMath, Viewport
|
||||
from set_devices.qt_ports.plot_drag import PlotDragInteraction
|
||||
|
||||
|
||||
class Canvas(PlotDragInteraction, QWidget):
|
||||
view_changed = Signal()
|
||||
|
||||
def __init__(self, core):
|
||||
super().__init__()
|
||||
self.core = core
|
||||
self.viewport = Viewport(.25, .25, .5, .5)
|
||||
self.markers = replace(Markers(a=40, b=60, e=50, f=65), y_enabled=True)
|
||||
self.marker_mode = QCheckBox(self)
|
||||
self.marker_mode.setChecked(True)
|
||||
self.marker_mode.hide()
|
||||
self.has_plot_data = True
|
||||
self.lock_x = self.lock_y = False
|
||||
self._press = self._dragged = None
|
||||
self.single_clicks = []
|
||||
self.resize(440, 340)
|
||||
|
||||
@property
|
||||
def visible_bounds(self):
|
||||
return Bounds(0, 100, 0, 100).visible(self.core, self.viewport)
|
||||
|
||||
def plot_rect(self):
|
||||
return QRectF(20, 20, 400, 300)
|
||||
|
||||
def value_rect(self):
|
||||
return QRectF(20, 20, 400, 200)
|
||||
|
||||
def _refresh_controls(self):
|
||||
pass
|
||||
|
||||
def _single_cursor_click(self, pos):
|
||||
self.single_clicks.append(pos)
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get('SETPROTOCOL_LIBRARY'), 'Set SETPROTOCOL_LIBRARY')
|
||||
class PlotDragTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.app = QApplication.instance() or QApplication([])
|
||||
cls.core = PlotMath(ctypes.CDLL(os.environ['SETPROTOCOL_LIBRARY']))
|
||||
|
||||
def setUp(self):
|
||||
self.plot = Canvas(self.core)
|
||||
self.plot.show()
|
||||
self.app.processEvents()
|
||||
|
||||
def tearDown(self):
|
||||
self.plot.close()
|
||||
|
||||
def drag(self, start, end, modifiers=Qt.NoModifier):
|
||||
QTest.mousePress(self.plot, Qt.LeftButton, modifiers, start)
|
||||
QTest.mouseRelease(self.plot, Qt.LeftButton, modifiers, end)
|
||||
|
||||
def test_empty_space_pans_x_and_preserves_markers(self):
|
||||
before, markers = self.plot.viewport, self.plot.markers
|
||||
self.drag(QPoint(220, 180), QPoint(260, 210))
|
||||
self.assertEqual(before.transform(self.core, pan_x=.1), self.plot.viewport)
|
||||
self.assertEqual(markers, self.plot.markers)
|
||||
|
||||
def test_shift_over_marker_pans_only_y_and_respects_lock(self):
|
||||
before, markers = self.plot.viewport, self.plot.markers
|
||||
self.drag(QPoint(140, 180), QPoint(180, 200), Qt.ShiftModifier)
|
||||
self.assertEqual(before.transform(self.core, pan_y=.1), self.plot.viewport)
|
||||
self.assertEqual(markers, self.plot.markers)
|
||||
self.plot.lock_y = True
|
||||
before = self.plot.viewport
|
||||
self.drag(QPoint(140, 180), QPoint(180, 200), Qt.ShiftModifier)
|
||||
self.assertEqual(before, self.plot.viewport)
|
||||
|
||||
def test_marker_capture_in_analog_and_digital_panes(self):
|
||||
before = self.plot.viewport
|
||||
# X marker A at x=140 remains draggable in a digital lane.
|
||||
self.drag(QPoint(145, 270), QPoint(185, 290))
|
||||
self.assertAlmostEqual(45, self.plot.markers.a)
|
||||
self.assertEqual(before, self.plot.viewport)
|
||||
# Y marker E at y=120 uses the analog pane's height.
|
||||
self.drag(QPoint(220, 125), QPoint(240, 145))
|
||||
self.assertAlmostEqual(45, self.plot.markers.e)
|
||||
self.assertEqual(before, self.plot.viewport)
|
||||
|
||||
def test_click_miss_and_locked_x_do_not_move_markers(self):
|
||||
before, markers = self.plot.viewport, self.plot.markers
|
||||
self.drag(QPoint(220, 180), QPoint(220, 180))
|
||||
self.assertEqual(before, self.plot.viewport)
|
||||
self.assertEqual(markers, self.plot.markers)
|
||||
self.assertEqual(1, len(self.plot.single_clicks))
|
||||
self.plot.lock_x = True
|
||||
self.drag(QPoint(220, 180), QPoint(260, 210))
|
||||
self.assertEqual(before, self.plot.viewport)
|
||||
self.assertEqual(markers, self.plot.markers)
|
||||
self.assertEqual(1, len(self.plot.single_clicks))
|
||||
|
||||
def test_marker_click_and_drag_returning_to_start_are_not_single_clicks(self):
|
||||
point = QPoint(220, 180)
|
||||
self.drag(QPoint(140, 180), QPoint(140, 180))
|
||||
QTest.mousePress(self.plot, Qt.LeftButton, pos=point)
|
||||
moved = point + QPoint(40, 0)
|
||||
event = QMouseEvent(QEvent.MouseMove, QPointF(moved),
|
||||
QPointF(self.plot.mapToGlobal(moved)),
|
||||
Qt.NoButton, Qt.LeftButton, Qt.NoModifier)
|
||||
self.app.sendEvent(self.plot, event)
|
||||
QTest.mouseRelease(self.plot, Qt.LeftButton, pos=point)
|
||||
self.assertEqual([], self.plot.single_clicks)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user