1
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2026-03-08 01:37:52 +01:00

feat: added qt_utils package with general Crosshair function

* only emits int -> suitable for 2D coordinates but not for 1D plot
This commit is contained in:
wyzula-jan
2023-08-10 10:50:47 +02:00
parent 0f109e6ad3
commit 5353fed7bf
4 changed files with 132 additions and 15 deletions

View File

@@ -61,7 +61,7 @@ class BasicPlot(QtWidgets.QWidget):
"symbol": "o",
"symbolSize": 10,
}
color_list = ["#384c6b", "#e28a2b", "#5E3023", "#e41a1c", "#984e83", "#4daf4a"]
color_list = BasicPlot.golden_angle_color(colormap="CET-R2", num=len(self.y_value_list))
# setup plots - GraphicsLayoutWidget
@@ -126,7 +126,7 @@ class BasicPlot(QtWidgets.QWidget):
# Debug functions
self.pushButton_debug.clicked.connect(self.generate_2D_data_update)
self.generate_2D_data()
# self.generate_2D_data()
self._current_proj = None
self._current_metadata_ep = "px_stream/projection_{}/metadata"
@@ -187,18 +187,18 @@ class BasicPlot(QtWidgets.QWidget):
closest_point = self.closest_x_y_value(
mousePoint.x(), self.plotter_data_x[0], self.plotter_data_y[0]
)
self.precision = 3
ii = 0
y_value = self.y_value_list[ii]
x_data = f"{10**closest_point[0]:.{self.precision}f}"
y_data = f"{10**closest_point[1]:.{self.precision}f}"
# Write coordinate to QTable
self.mouse_table.setItem(ii, 1, QTableWidgetItem(str(y_value)))
self.mouse_table.setItem(ii, 2, QTableWidgetItem(str(x_data)))
self.mouse_table.setItem(ii, 3, QTableWidgetItem(str(y_data)))
self.mouse_table.resizeColumnsToContents()
# self.precision = 3
# ii = 0
# y_value = self.y_value_list[ii]
# x_data = f"{10**closest_point[0]:.{self.precision}f}"
# y_data = f"{10**closest_point[1]:.{self.precision}f}"
#
# # Write coordinate to QTable
# self.mouse_table.setItem(ii, 1, QTableWidgetItem(str(y_value)))
# self.mouse_table.setItem(ii, 2, QTableWidgetItem(str(x_data)))
# self.mouse_table.setItem(ii, 3, QTableWidgetItem(str(y_data)))
#
# self.mouse_table.resizeColumnsToContents()
def closest_x_y_value(self, input_value, list_x, list_y) -> tuple:
"""
@@ -382,7 +382,7 @@ class BasicPlot(QtWidgets.QWidget):
time.sleep(0.1)
continue
endpoint = f"px_stream/projection_{self._current_proj}/data"
msgs = client.producer.lrange(topic=endpoint, start=0, end=0)
msgs = client.producer.lrange(topic=endpoint, start=-1, end=-1)
data = [BECMessage.DeviceMessage.loads(msg) for msg in msgs]
if not data:
continue

View File

View File

@@ -0,0 +1,46 @@
import pyqtgraph as pg
import numpy as np
from PyQt5.QtCore import pyqtSignal, QObject
class Crosshair(QObject):
coordinatesChanged = pyqtSignal(float, float)
dataPointClicked = pyqtSignal(float, float)
def __init__(self, plot_item, is_image=False, parent=None):
super().__init__(parent)
self.plot_item = plot_item
self.data_shape = None
self.is_image = is_image
self.v_line = pg.InfiniteLine(angle=90, movable=False)
self.h_line = pg.InfiniteLine(angle=0, movable=False)
self.plot_item.addItem(self.v_line, ignoreBounds=True)
self.plot_item.addItem(self.h_line, ignoreBounds=True)
self.proxy = pg.SignalProxy(
self.plot_item.scene().sigMouseMoved, rateLimit=60, slot=self.mouse_moved
)
self.plot_item.scene().sigMouseClicked.connect(self.mouse_clicked)
def mouse_moved(self, event):
pos = event[0]
if self.data_shape is not None and self.plot_item.vb.sceneBoundingRect().contains(pos):
mouse_point = self.plot_item.vb.mapSceneToView(pos)
x = int(np.clip(np.round(mouse_point.x()), 0, self.data_shape[1] - 1))
y = int(np.clip(np.round(mouse_point.y()), 0, self.data_shape[0] - 1))
self.v_line.setPos(x)
self.h_line.setPos(y)
self.coordinatesChanged.emit(x, y)
def mouse_clicked(self, event):
if self.data_shape is not None and self.plot_item.vb.sceneBoundingRect().contains(
event._scenePos
):
mouse_point = self.plot_item.vb.mapSceneToView(event._scenePos)
x = int(np.clip(np.round(mouse_point.x()), 0, self.data_shape[1] - 1))
y = int(np.clip(np.round(mouse_point.y()), 0, self.data_shape[0] - 1))
self.v_line.setPos(x)
self.h_line.setPos(y)
self.dataPointClicked.emit(x, y)
def set_data_shape(self, shape):
self.data_shape = shape

View File

@@ -0,0 +1,71 @@
import pyqtgraph as pg
import numpy as np
from crosshair import Crosshair
def add_crosshair(plot_item, is_image=False):
return Crosshair(plot_item, is_image)
app = pg.mkQApp()
win = pg.GraphicsLayoutWidget(show=True)
win.resize(1000, 500)
#####################
# 1D Plot with labels
#####################
label_1d_move = win.addLabel("1D move label", row=0, col=0)
label_1d_click = win.addLabel("1D click label", row=1, col=0)
plot_item_1d = win.addPlot(row=2, col=0)
x_data = np.linspace(0, 10, 1000)
y_data = np.sin(x_data)
plot_item_1d.plot(x_data, y_data)
#
crosshair_1d = add_crosshair(plot_item_1d)
crosshair_1d.set_data_shape((len(y_data), len(x_data)))
#
def on_coordinates_changed_1d(x, y):
label_1d_move.setText(f"1D Moved: ({x}, {y})")
def on_data_point_clicked_1d(x, y):
label_1d_click.setText(f"1D Clicked: ({x}, {y})")
#
crosshair_1d.coordinatesChanged.connect(on_coordinates_changed_1d)
crosshair_1d.dataPointClicked.connect(on_data_point_clicked_1d)
#####################
# 2D Plot with labels
#####################
label_2d_move = win.addLabel("2D move label", row=0, col=1)
label_2d_click = win.addLabel("2D click label", row=1, col=1)
plot_item_2d = win.addPlot(row=2, col=1)
img = np.random.normal(size=(100, 100))
image_item = pg.ImageItem(img)
plot_item_2d.addItem(image_item)
crosshair_2d = add_crosshair(plot_item_2d, is_image=True)
crosshair_2d.set_data_shape(img.shape)
#
def on_coordinates_changed_2d(x, y):
label_2d_move.setText(f"2D Moved: ({x}, {y})")
def on_data_point_clicked_2d(x, y):
label_2d_click.setText(f"2D Clicked: ({x}, {y})")
#
crosshair_2d.coordinatesChanged.connect(on_coordinates_changed_2d)
crosshair_2d.dataPointClicked.connect(on_data_point_clicked_2d)
if __name__ == "__main__":
pg.exec()