Skip to content

Commit c06b852

Browse files
committed
fix: QuickView issues when removing datasets (close #25)
1 parent f497555 commit c06b852

File tree

6 files changed

+93
-23
lines changed

6 files changed

+93
-23
lines changed

.travis.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
notifications:
22
email: false
3-
sudo: required
3+
addons:
4+
apt:
5+
packages:
6+
# These packages are required for testing PyQT5 applications on linux
7+
- x11-utils
8+
- libxkbcommon-x11-0
49
matrix:
510
include:
611
- os: osx
712
language: generic
813
env: MAC_PYTHON_VERSION=3.6
14+
sudo: required
915
- os: linux
1016
language: python
1117
python: 3.6
12-
before_install:
18+
services: xvfb
19+
install:
1320
# install other dependencies
1421
- source ./.travis/${TRAVIS_OS_NAME}_setup_python.sh $MAC_PYTHON_VERSION
15-
install:
1622
# install binary packages
1723
- travis_retry pip install --upgrade pip
1824
- travis_retry pip install setuptools wheel

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
2.0.0b3
22
- enh: introduce FilterRay class for caching of hierarchy data (#6)
33
- fix: minor plot updating issues
4+
- fix: QuickView issues when removing datasets (#25)
45
2.0.0b2
56
- feat: support loading sessions with missing dataset paths (#5)
67
- fix: don't use area_um, deform, and bright_avg box filters by

shapeout2/gui/main.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ def adopt_slot(self, slot_state):
278278
raise ValueError("Slot not in pipeline: {}".format(slot_id))
279279
self.adopt_pipeline(state)
280280

281+
@QtCore.pyqtSlot()
281282
def add_dataslot(self, paths=None):
282283
"""Adds a dataslot to the pipeline"""
283284
if paths is None:
@@ -404,18 +405,20 @@ def on_action_develop(self, b):
404405
msg.setWindowTitle("Restart Shape-Out")
405406
msg.exec_()
406407

407-
def on_action_clear(self):
408-
buttonReply = QtWidgets.QMessageBox.question(
409-
self, 'Clear Session', "All progress will be lost. Continue?",
410-
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
411-
QtWidgets.QMessageBox.No)
412-
if buttonReply == QtWidgets.QMessageBox.Yes:
408+
@QtCore.pyqtSlot()
409+
def on_action_clear(self, assume_yes=False):
410+
if assume_yes:
411+
yes = True
412+
else:
413+
buttonReply = QtWidgets.QMessageBox.question(
414+
self, 'Clear Session', "All progress will be lost. Continue?",
415+
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
416+
QtWidgets.QMessageBox.No)
417+
yes = buttonReply == QtWidgets.QMessageBox.Yes
418+
if yes:
413419
session.clear_session(self.pipeline)
414420
self.adopt_pipeline(self.pipeline.__getstate__())
415-
ret = True
416-
else:
417-
ret = False
418-
return ret
421+
return yes
419422

420423
def on_action_docs(self):
421424
webbrowser.open("https://shapeout2.readthedocs.io")

shapeout2/gui/matrix/data_matrix.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,11 @@ def get_matrix_indices(self, slot_id, filt_id):
348348
def get_quickview_ids(self):
349349
current = MatrixElement._quick_view_instance
350350
if current is not None:
351-
state = self.__getstate__()
351+
try:
352+
state = self.__getstate__()
353+
except KeyError:
354+
# the state is not valid (issue #25)
355+
return None, None
352356
for slot_id in state["elements"]:
353357
ds_state = state["elements"][slot_id]
354358
for filt_id in ds_state:

shapeout2/gui/quick_view/qv_main.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,14 @@ def __init__(self, *args, **kwargs):
2626

2727
self.setWindowTitle("Quick View (QV)")
2828

29-
# Initially, only show the info about how QuickView works
30-
self.widget_tool.setEnabled(False)
31-
self.widget_scatter.hide()
29+
self._set_initial_ui()
3230

3331
# Set scale options (with data)
3432
for cb in [self.comboBox_xscale, self.comboBox_yscale]:
3533
cb.clear()
3634
cb.addItem("linear", "linear")
3735
cb.addItem("logarithmic", "log")
3836

39-
# Hide settings/events by default
40-
self.widget_event.setVisible(False)
41-
self.widget_settings.setVisible(False)
42-
self.widget_poly.setVisible(False)
43-
4437
# settings button
4538
self.toolButton_event.toggled.connect(self.on_tool)
4639
self.toolButton_poly.toggled.connect(self.on_tool)
@@ -120,7 +113,7 @@ def __init__(self, *args, **kwargs):
120113
)
121114

122115
# set initial empty dataset
123-
self.rtdc_ds = None
116+
self._rtdc_ds = None
124117

125118
# init events/features table
126119
self.tableWidget_feats.setColumnCount(2)
@@ -185,6 +178,34 @@ def __setstate__(self, state):
185178
self.checkBox_trace_raw.setChecked(event["trace raw"])
186179
self.checkBox_trace_legend.setChecked(event["trace legend"])
187180

181+
def _set_initial_ui(self):
182+
# Initially, only show the info about how QuickView works
183+
self.widget_tool.setEnabled(False)
184+
self.widget_scatter.hide()
185+
# Hide settings/events by default
186+
self.widget_event.hide()
187+
self.widget_settings.hide()
188+
self.widget_poly.hide()
189+
# show the how-to label
190+
self.label_howto.show()
191+
192+
@property
193+
def rtdc_ds(self):
194+
"""Dataset to plot; set to None initially and if the file is closed"""
195+
if self._rtdc_ds is not None:
196+
if isinstance(self._rtdc_ds, dclab.rtdc_dataset.RTDC_HDF5):
197+
if not self._rtdc_ds._h5:
198+
# the file is closed
199+
self._rtdc_ds = None
200+
# now check again
201+
if self._rtdc_ds is None:
202+
self._set_initial_ui()
203+
return self._rtdc_ds
204+
205+
@rtdc_ds.setter
206+
def rtdc_ds(self, rtdc_ds):
207+
self._rtdc_ds = rtdc_ds
208+
188209
def get_event_image(self, ds, event):
189210
state = self.__getstate__()
190211
imkw = self.imkw.copy()

tests/test_gui_quickview.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Test of data set functionalities"""
2+
import pathlib
3+
4+
from PyQt5 import QtCore
5+
6+
from shapeout2.gui.main import ShapeOut2
7+
8+
9+
def test_simple(qtbot):
10+
"""Open the main window and close it again"""
11+
main_window = ShapeOut2()
12+
main_window.close()
13+
14+
15+
def test_quickview_issue_25(qtbot):
16+
mw = ShapeOut2()
17+
qtbot.addWidget(mw)
18+
19+
# add a dataslot
20+
path = pathlib.Path(__file__).parent / "data" / "calibration_beads_47.rtdc"
21+
mw.add_dataslot(paths=[path])
22+
23+
assert len(mw.pipeline.slot_ids) == 1, "we added that"
24+
assert len(mw.pipeline.filter_ids) == 1, "automatically added"
25+
26+
# activate a dataslot
27+
slot_id = mw.pipeline.slot_ids[0]
28+
filt_id = mw.pipeline.filter_ids[0]
29+
em = mw.block_matrix.get_widget(slot_id, filt_id)
30+
qtbot.mouseClick(em, QtCore.Qt.LeftButton, QtCore.Qt.ShiftModifier)
31+
# did that work?
32+
assert mw.toolButton_quick_view.isChecked()
33+
34+
# now clear the session (this raised the errror in #25)
35+
mw.on_action_clear(assume_yes=True)

0 commit comments

Comments
 (0)