first try on adding 2D image support
This commit is contained in:
48
grum/imgdesc.py
Normal file
48
grum/imgdesc.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
class ImageDescription:
|
||||||
|
|
||||||
|
def __init__(self, name, title=None, xlabel=None, ylabel=None, image=None):
|
||||||
|
self.name = name
|
||||||
|
self.title = title
|
||||||
|
self.xlabel = xlabel
|
||||||
|
self.ylabel = ylabel
|
||||||
|
self.image = image
|
||||||
|
|
||||||
|
@property
|
||||||
|
def data(self):
|
||||||
|
return np.asarray(self.image)
|
||||||
|
|
||||||
|
@data.setter
|
||||||
|
def data(self, value):
|
||||||
|
self.image = value
|
||||||
|
|
||||||
|
|
||||||
|
def append(self, xy):
|
||||||
|
print("ignored image append")
|
||||||
|
|
||||||
|
def extend(self, data):
|
||||||
|
print("ignored image extend")
|
||||||
|
|
||||||
|
|
||||||
|
def make_plot(self, plotwidget, style):
|
||||||
|
res = plotwidget.setImage(self.data)
|
||||||
|
|
||||||
|
if self.title:
|
||||||
|
plotwidget.setTitle(self.title)
|
||||||
|
|
||||||
|
if self.xlabel:
|
||||||
|
plotwidget.setLabel("bottom", self.xlabel)
|
||||||
|
|
||||||
|
if self.ylabel:
|
||||||
|
plotwidget.setLabel("left", self.ylabel)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {k: v for k, v in self.__dict__.items() if not k.startswith("_") and k != "name" and v is not None}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6,9 +6,10 @@ from .dictlist import DictList
|
|||||||
from .exampledata import exampledata
|
from .exampledata import exampledata
|
||||||
from .h5filedlg import open_h5_files_dialog, save_h5_file_dialog
|
from .h5filedlg import open_h5_files_dialog, save_h5_file_dialog
|
||||||
from .io import write_dict, read_dict
|
from .io import write_dict, read_dict
|
||||||
from .mdi import MDIArea, MDISubMultiPlot, MDISubPlot, MDIWindowMode
|
from .mdi import MDIArea, MDISubMultiPlot, MDISubPlot, MDISubImage, MDIWindowMode
|
||||||
from .menus import BarMenu
|
from .menus import BarMenu
|
||||||
from .plotdesc import PlotDescription
|
from .plotdesc import PlotDescription
|
||||||
|
from .imgdesc import ImageDescription
|
||||||
from .rpc import RPCServerThread
|
from .rpc import RPCServerThread
|
||||||
from .shortcut import shortcut
|
from .shortcut import shortcut
|
||||||
from .webview import WebView
|
from .webview import WebView
|
||||||
@ -16,7 +17,8 @@ from .webview import WebView
|
|||||||
|
|
||||||
class MainWindow(QMainWindow):
|
class MainWindow(QMainWindow):
|
||||||
|
|
||||||
sig_make_new_plot = pyqtSignal(str, PlotDescription)
|
sig_make_new_plot = pyqtSignal(str, PlotDescription)
|
||||||
|
sig_make_new_image = pyqtSignal(str, ImageDescription)
|
||||||
|
|
||||||
def __init__(self, *args, title="grum", host="localhost", port=8000, offline=False, add_examples=False, window_mode=MDIWindowMode.MULTI, **kwargs):
|
def __init__(self, *args, title="grum", host="localhost", port=8000, offline=False, add_examples=False, window_mode=MDIWindowMode.MULTI, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -88,8 +90,10 @@ class MainWindow(QMainWindow):
|
|||||||
rst.server.register_function(self.append_data)
|
rst.server.register_function(self.append_data)
|
||||||
rst.server.register_function(self.extend_data)
|
rst.server.register_function(self.extend_data)
|
||||||
rst.server.register_function(self.set_data)
|
rst.server.register_function(self.set_data)
|
||||||
|
rst.server.register_function(self.new_image)
|
||||||
|
|
||||||
self.sig_make_new_plot.connect(self.on_make_new_plot)
|
self.sig_make_new_plot.connect(self.on_make_new_plot)
|
||||||
|
self.sig_make_new_image.connect(self.on_make_new_image)
|
||||||
|
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
@ -140,12 +144,29 @@ class MainWindow(QMainWindow):
|
|||||||
desc.data = data
|
desc.data = data
|
||||||
self.sync_item_and_plots(item)
|
self.sync_item_and_plots(item)
|
||||||
|
|
||||||
|
def new_image(self, name, cfg):
|
||||||
|
"""
|
||||||
|
Create a new image <name> using the configuration dict <cfg>.
|
||||||
|
The configuration is forwarded to the constructor of ImageDescription.
|
||||||
|
Allowed keys are: title, xlabel, ylabel, image.
|
||||||
|
"""
|
||||||
|
desc = self.add_new_desc_to_list(name, cfg, Desc=ImageDescription) #TODO: clean up Desc argument
|
||||||
|
if self.menu_settings.checkboxes["Open new plots"].isChecked():
|
||||||
|
sub = self.mdi.findSubWindow(name)
|
||||||
|
if sub:
|
||||||
|
sub.pw.setImage(desc.data) #TODO lacks the list sync
|
||||||
|
else:
|
||||||
|
self.sig_make_new_image.emit(name, desc)
|
||||||
|
|
||||||
|
|
||||||
# Signal callbacks
|
# Signal callbacks
|
||||||
|
|
||||||
def on_make_new_plot(self, *args, **kwargs):
|
def on_make_new_plot(self, *args, **kwargs):
|
||||||
self.make_subwin(MDISubPlot, *args, **kwargs)
|
self.make_subwin(MDISubPlot, *args, **kwargs)
|
||||||
|
|
||||||
|
def on_make_new_image(self, *args, **kwargs):
|
||||||
|
self.make_subwin(MDISubImage, *args, **kwargs)
|
||||||
|
|
||||||
def on_dclick_list_item(self, item):
|
def on_dclick_list_item(self, item):
|
||||||
self.plot_single_item(item)
|
self.plot_single_item(item)
|
||||||
|
|
||||||
@ -188,7 +209,8 @@ class MainWindow(QMainWindow):
|
|||||||
for fn in fns:
|
for fn in fns:
|
||||||
data = read_dict(fn)
|
data = read_dict(fn)
|
||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
self.add_new_desc_to_list(k, v)
|
Desc = ImageDescription if "image" in v else PlotDescription #TODO
|
||||||
|
self.add_new_desc_to_list(k, v, Desc=Desc)
|
||||||
|
|
||||||
|
|
||||||
def on_file_save(self):
|
def on_file_save(self):
|
||||||
@ -206,8 +228,8 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# Plumbing
|
# Plumbing
|
||||||
|
|
||||||
def add_new_desc_to_list(self, name, cfg):
|
def add_new_desc_to_list(self, name, cfg, Desc=PlotDescription): #TODO
|
||||||
desc = PlotDescription(name, **cfg)
|
desc = Desc(name, **cfg)
|
||||||
self.lst.set(name, desc)
|
self.lst.set(name, desc)
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
@ -226,7 +248,8 @@ class MainWindow(QMainWindow):
|
|||||||
item.timestamps.access.update()
|
item.timestamps.access.update()
|
||||||
item.set_alarm(False)
|
item.set_alarm(False)
|
||||||
name, desc = item.key, item.value
|
name, desc = item.key, item.value
|
||||||
self.activate_or_make_subwin(MDISubPlot, name, desc)
|
MDISubType = MDISubImage if isinstance(desc, ImageDescription) else MDISubPlot #TODO
|
||||||
|
self.activate_or_make_subwin(MDISubType, name, desc)
|
||||||
|
|
||||||
def plot_multiple_items(self, items):
|
def plot_multiple_items(self, items):
|
||||||
for i in items:
|
for i in items:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
from .mdiarea import MDIArea, MDIWindowMode
|
from .mdiarea import MDIArea, MDIWindowMode
|
||||||
from .mdisubplot import MDISubPlot, MDISubMultiPlot
|
from .mdisubplot import MDISubPlot, MDISubMultiPlot
|
||||||
|
from .mdisubimg import MDISubImage
|
||||||
|
|
||||||
|
|
||||||
|
38
grum/mdi/mdisubimg.py
Normal file
38
grum/mdi/mdisubimg.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import pyqtgraph as pg
|
||||||
|
from .mdisubwin import MDISubWindow
|
||||||
|
from ..theme import pg_plot_style
|
||||||
|
|
||||||
|
|
||||||
|
class MDISubImage(MDISubWindow):
|
||||||
|
|
||||||
|
def __init__(self, name, desc, *args, **kwargs):
|
||||||
|
super().__init__(name, *args, **kwargs)
|
||||||
|
self.pw = pw = pg.ImageView()
|
||||||
|
self.setWidget(pw)
|
||||||
|
|
||||||
|
# connect to plot mouse-over event
|
||||||
|
pw.scene.sigMouseMoved.connect(self.on_hover)
|
||||||
|
|
||||||
|
style = pg_plot_style()
|
||||||
|
|
||||||
|
plot = desc.make_plot(self.pw, style)
|
||||||
|
self.plots = {name: plot}
|
||||||
|
|
||||||
|
self.image = desc.data
|
||||||
|
|
||||||
|
|
||||||
|
def on_hover(self, event):
|
||||||
|
coord = self.pw.imageItem.mapFromScene(event)
|
||||||
|
x = coord.x()
|
||||||
|
y = coord.y()
|
||||||
|
x = int(x)
|
||||||
|
y = int(y)
|
||||||
|
try:
|
||||||
|
z = self.image[x, y]
|
||||||
|
except IndexError:
|
||||||
|
return
|
||||||
|
z = round(z, 3)
|
||||||
|
self.setToolTip(f"x = {x}\ny = {y}\nz = {z}")
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user