42 from typing
import Any, Callable, Dict
45 import pyqtgraph
as pg
48 from PyQt5
import QtWidgets
49 from PyQt5.QtCore
import QThread, QTimer
50 from PyQt5.uic
import loadUiType
51 except ModuleNotFoundError
as e:
53 from PySide2
import QtWidgets
54 from PySide2.QtCore
import QThread, QTimer
55 from PySide2.QtUiTools
import loadUiType
56 except ModuleNotFoundError
as e:
57 raise ModuleNotFoundError(
"No module named 'PyQt5' or PySide2', please install one of them\nException raised: "+e.msg)
59 from pyqtgraph.dockarea
import Dock, DockArea
65 return loadUiType(os.environ[
"SHESHA_ROOT"] +
66 "/shesha/widgets/%s.ui" % moduleName)
69 BaseWidgetTemplate, BaseClassTemplate =
uiLoader(
'widget_base')
75 """x and y are 2D arrays of shape (Nplots, Nsamples)"""
76 connect = np.ones(x.shape, dtype=bool)
78 self.
pathpath = pg.arrayToQPath(x.flatten(), y.flatten(), connect.flatten())
79 pg.QtGui.QGraphicsPathItem.__init__(self, self.
pathpath)
80 self.setPen(pg.mkPen(
'r'))
83 return pg.QtGui.QGraphicsItem.shape(self)
91 def __init__(self, parent=None, hide_histograms=False) -> None:
92 BaseClassTemplate.__init__(self, parent=parent)
94 self.
uiBaseuiBase = BaseWidgetTemplate()
95 self.
uiBaseuiBase.setupUi(self)
103 if self.
uiBaseuiBase.wao_Display.isChecked():
104 self.
gui_timergui_timer.start(1000. / self.
uiBaseuiBase.wao_frameRate.value())
113 self.
uiBaseuiBase.wao_DisplayDock.setWidget(self.
areaarea)
123 self.
uiBaseuiBase.wao_loadArea.clicked.connect(self.
loadArealoadArea)
124 self.
uiBaseuiBase.wao_saveArea.clicked.connect(self.
saveAreasaveArea)
129 self.
uiBaseuiBase.wao_frameRate.setValue(2)
131 self.
uiBaseuiBase.wao_load_config.setDisabled(
False)
132 self.
uiBaseuiBase.wao_init.setDisabled(
True)
144 self.
uiBaseuiBase.wao_frameRate.setDisabled(state)
146 self.
gui_timergui_timer.start(1000. / self.
uiBaseuiBase.wao_frameRate.value())
154 reply = QtWidgets.QMessageBox.question(
155 self,
'Message',
"Are you sure to quit?", QtWidgets.QMessageBox.Yes |
156 QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No)
158 if reply == QtWidgets.QMessageBox.Yes:
170 def saveArea(self, widget, filename=None):
172 Callback when a area layout file is double clicked in the file browser
173 Place the selected file name in the browsing drop-down menu,
174 the call the self.load_config callback of the load button.
177 filepath = QtWidgets.QFileDialog(
179 self,
"Select area layout file",
"",
180 "area layout file (*.area);;all files (*)")
181 filename = filepath[0]
184 with open(filename,
"w+")
as f:
185 st = self.
areaarea.saveState()
187 except FileNotFoundError
as err:
188 warnings.warn(filename +
" not loaded: " + err)
192 if disp_checkbox.text() == name:
193 disp_checkbox.setChecked(
True)
195 if name
in self.
docksdocks.keys():
196 self.
areaarea.addDock(self.
docksdocks[name])
199 typ, contents, _ = state
210 disp_checkbox.setChecked(
False)
211 for dock
in self.
docksdocks.values():
216 filepath = QtWidgets.QFileDialog(
218 self,
"Select area layout file",
"",
219 "area layout file (*.area);;all files (*)")
220 filename = filepath[0]
223 with open(filename,
"r")
as f:
224 st = eval(f.readline())
227 if st[
'main']
is not None:
231 for win
in st[
"float"]:
235 self.
areaarea.restoreState(st)
236 except FileNotFoundError
as err:
237 warnings.warn(filename +
"not loaded: " + err)
241 Callback when a config file is double clicked in the file browser
242 Place the selected file name in the browsing drop-down menu,
243 the call the self.load_config callback of the load button.
245 filepath = QtWidgets.QFileDialog(directory=self.
defaultParPathdefaultParPath).getOpenFileName(
246 self,
"Select parameter file",
"",
247 "parameters file (*.py);;hdf5 file (*.h5);;all files (*)")
249 self.
uiBaseuiBase.wao_selectConfig.clear()
250 self.
uiBaseuiBase.wao_selectConfig.addItem(str(filepath[0]))
252 self.
load_configload_config(config_file=self.
uiBaseuiBase.wao_selectConfig.currentText())
255 guilty_guy = self.sender().text()
256 state = self.sender().isChecked()
258 self.
areaarea.addDock(self.
docksdocks[guilty_guy])
259 elif self.
docksdocks[guilty_guy].isVisible():
260 self.
docksdocks[guilty_guy].close()
262 def add_dispDock(self, name: str, parent, type: str =
"pg_image") -> Dock:
263 checkBox = QtWidgets.QCheckBox(name, parent)
265 checkableAction = QtWidgets.QWidgetAction(parent)
266 checkableAction.setDefaultWidget(checkBox)
267 parent.addAction(checkableAction)
271 self.
docksdocks[name] = d
272 if type ==
"pg_image":
273 img = pg.ImageItem(border=
'w', image=np.zeros((2,2)))
274 self.
imgsimgs[name] = img
276 viewbox = pg.ViewBox()
278 viewbox.setAspectLocked(
True)
281 viewbox.invertY(
False)
283 iv = pg.ImageView(view=viewbox, imageItem=img)
285 cmap = pg.colormap.get(
'viridis')
290 iv.ui.histogram.hide()
291 iv.ui.histogram.autoHistogramRange()
292 iv.ui.histogram.setMaximumWidth(100)
296 elif type ==
"pg_plot":
297 img = pg.PlotItem(border=
'w')
298 self.
imgsimgs[name] = img
302 self.
imgsimgs[name] = img
310 Callback when 'LOAD' button is hit
313 self.
uiBaseuiBase.wao_phasesgroup_tb, self.
uiBaseuiBase.wao_imagesgroup_tb,
314 self.
uiBaseuiBase.wao_graphgroup_tb
316 layout = groupbox.menu()
317 while layout
and not layout.isEmpty():
318 w = layout.children()[0]
319 layout.removeAction(w)
324 for _, dock
in self.
docksdocks.items():
328 self.
docksdocks.clear()
329 self.
imgsimgs.clear()
334 self.
uiBaseuiBase.wao_phasesgroup_tb.setText(
'Select')
335 self.
uiBaseuiBase.wao_phasesgroup_tb.setPopupMode(QtWidgets.QToolButton.InstantPopup)
339 self.
uiBaseuiBase.wao_graphgroup_tb.setText(
'Select')
340 self.
uiBaseuiBase.wao_graphgroup_tb.setPopupMode(QtWidgets.QToolButton.InstantPopup)
342 self.
uiBaseuiBase.wao_imagesgroup_tb.setText(
'Select')
345 self.
uiBaseuiBase.wao_imagesgroup_tb.setPopupMode(QtWidgets.QToolButton.InstantPopup)
357 parlist = sorted(glob.glob(self.
defaultParPathdefaultParPath +
"/*.py"))
358 self.
uiBaseuiBase.wao_selectConfig.clear()
359 self.
uiBaseuiBase.wao_selectConfig.addItems([
360 parlist[i].
split(
'/')[-1]
for i
in range(len(parlist))
365 self.
uiBaseuiBase.wao_load_config.setDisabled(
True)
366 self.
uiBaseuiBase.wao_init.setDisabled(
True)
375 self.uiBase.wao_load_config.setDisabled(
False)
376 self.uiBase.wao_init.setDisabled(
False)
377 self.loopLock.release()
380 if not self.
loopLockloopLock.acquire(
False):
388 def addSHGrid(self, pg_image, valid_sub, sspsize, pitch):
391 pg_image.removeItem(self.
PupilLinesPupilLines)
393 nssp_tot = valid_sub[0].size
394 connect = np.ones((nssp_tot, 5), dtype=bool)
396 roi_x = np.ones((nssp_tot, 5), dtype=int)
397 roi_y = np.ones((nssp_tot, 5), dtype=int)
398 for idx_ssp
in range(nssp_tot):
399 (x, y) = (valid_sub[0][idx_ssp], valid_sub[1][idx_ssp])
400 roi_x[idx_ssp, :] = [x, x, x + sspsize, x + sspsize, x]
401 roi_y[idx_ssp, :] = [y, y + sspsize, y + sspsize, y, y]
407 print(text, end=
'\r', flush=
True)
412 QTimer.singleShot(0, self.
runrun)
418 QThread.__init__(self)
void split(std::vector< std::string > &tokens, const std::string &text, char sep)