Skip to content

Commit

Permalink
Merge pull request #1343 from astrofrog/remove-timers
Browse files Browse the repository at this point in the history
Get rid of QTimers for updating the data collection and layer artist lists
  • Loading branch information
astrofrog authored Jul 13, 2017
2 parents 75bf94e + 24d204e commit 75bfd13
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 28 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Full changelog
v0.11.0 (unreleased)
--------------------

* Get rid of QTimers for updating the data collection and layer artist
lists, and instead refresh whenever a message is sent from the hub
(which results in immediate changes rather than waiting up to a
second for things to change). [#1343]

* Made it possible to delay callbacks from the Hub using the
``Hub.delay_callbacks`` context manager. Also fixed the Hub so that
it uses weak references to classes and methods wherever possible. [#1339]
Expand Down
26 changes: 12 additions & 14 deletions glue/core/qt/data_collection_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
from glue.icons.qt import layer_icon

from glue.core.qt.style_dialog import StyleDialog
from glue.utils import nonpartial
from glue.utils.qt import PyMimeData
from glue.core.message import Message

DATA_IDX = 0
SUBSET_IDX = 1
Expand Down Expand Up @@ -449,31 +449,19 @@ def mimeTypes(self):
return [LAYERS_MIME_TYPE]


class DataCollectionView(QtWidgets.QTreeView):
class DataCollectionView(QtWidgets.QTreeView, HubListener):
selection_changed = QtCore.Signal()

def __init__(self, parent=None):
super(DataCollectionView, self).__init__(parent)
self.doubleClicked.connect(self._edit)

# this keeps the full-row of the selection bar in-sync
self.pressed.connect(nonpartial(self._update_viewport))

# only edit label on model.new_item
self.setItemDelegate(LabeledDelegate())
self.setEditTriggers(self.NoEditTriggers)

self.setIconSize(QtCore.QSize(16, 16))

self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(nonpartial(self._update_viewport))
self._timer.start(1000)

def _update_viewport(self):
# We have to do this here to make sure we always get the latest
# viewport instance.
self.viewport().update()

def selected_layers(self):
idxs = self.selectedIndexes()
return self._model.glue_data(idxs)
Expand Down Expand Up @@ -511,6 +499,16 @@ def set_data_collection(self, data_collection):
self.setDropIndicatorShown(True)
self.setDragDropMode(QtWidgets.QAbstractItemView.DragOnly)

# Update when any message is emitted which would indicate a change in
# data collection content, colors, labels, etc. It's easier to simply
# listen to all events since the viewport update is fast.
data_collection.hub.subscribe(self, Message, handler=self._update_viewport)

def _update_viewport(self, *args, **kwargs):
# This forces the widget containing the list view to update/redraw,
# reflecting any changes in color/labels/content
self.viewport().update()

def edit_label(self, index):
if not (self._model.flags(index) & Qt.ItemIsEditable):
return
Expand Down
27 changes: 16 additions & 11 deletions glue/core/qt/layer_artist_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from glue.core.qt.mime import LAYERS_MIME_TYPE
from glue.utils import nonpartial
from glue.utils.qt import PythonListModel, PyMimeData

from glue.core.hub import HubListener
from glue.core.message import Message

class LayerArtistModel(PythonListModel):

Expand Down Expand Up @@ -169,13 +170,13 @@ def row_artist(self, row):
return self.artists[row]


class LayerArtistView(QtWidgets.QListView):
class LayerArtistView(QtWidgets.QListView, HubListener):

"""A list view into an artist model. The zorder
of each artist can be shuffled by dragging and dropping
items. Right-clicking brings up a menu to edit style or delete"""

def __init__(self, parent=None):
def __init__(self, parent=None, hub=None):
super(LayerArtistView, self).__init__(parent)
self.setDragEnabled(True)
self.setAcceptDrops(True)
Expand All @@ -190,13 +191,15 @@ def __init__(self, parent=None):
self._actions = {}
self._create_actions()

self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(nonpartial(self._update_viewport))
self._timer.start(1000)
# Update when any message is emitted which would indicate a change in
# data collection content, colors, labels, etc. It's easier to simply
# listen to all events since the viewport update is fast.
self.hub = hub
self.hub.subscribe(self, Message, self._update_viewport)

def _update_viewport(self):
# We have to do this here to make sure we always get the latest
# viewport instance.
def _update_viewport(self, *args):
# This forces the widget containing the list view to update/redraw,
# reflecting any changes in color/labels/content
self.viewport().update()

def rowsInserted(self, index, start, end):
Expand Down Expand Up @@ -283,16 +286,18 @@ class LayerArtistWidget(QtWidgets.QWidget):
options for the layer artists.
"""

def __init__(self, parent=None, layer_style_widget_cls=None):
def __init__(self, parent=None, layer_style_widget_cls=None, hub=None):

super(LayerArtistWidget, self).__init__(parent=parent)

self.hub = None

self.layout = QtWidgets.QVBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)

self.layer_style_widget_cls = layer_style_widget_cls

self.layer_list = LayerArtistView(parent=self)
self.layer_list = LayerArtistView(parent=self, hub=hub)
self.layout.addWidget(self.layer_list)

self.layer_options = QtWidgets.QWidget()
Expand Down
5 changes: 3 additions & 2 deletions glue/core/qt/tests/test_layer_artist_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from qtpy.QtCore import Qt
from qtpy import PYQT5
from glue.core import Data
from glue.core import Data, Hub
from glue.core.layer_artist import MatplotlibLayerArtist as _LayerArtist

from ..layer_artist_model import LayerArtistModel, LayerArtistView
Expand Down Expand Up @@ -217,7 +217,8 @@ class TestLayerArtistView(object):

def setup_method(self, method):
self.model, self.artists = setup_model(2)
self.view = LayerArtistView()
self.hub = Hub()
self.view = LayerArtistView(hub=self.hub)
self.view.setModel(self.model)

def test_current_row(self):
Expand Down
3 changes: 2 additions & 1 deletion glue/viewers/common/qt/data_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ def __init__(self, session, parent=None):
QtWidgets.QMainWindow.__init__(self, parent)
ViewerBase.__init__(self, session)
self.setWindowIcon(get_qapp().windowIcon())
self._view = LayerArtistWidget(layer_style_widget_cls=self._layer_style_widget_cls)
self._view = LayerArtistWidget(layer_style_widget_cls=self._layer_style_widget_cls,
hub=session.hub)
self._view.layer_list.setModel(self._layer_artist_container.model)
self._tb_vis = {} # store whether toolbars are enabled
self.setAttribute(Qt.WA_DeleteOnClose)
Expand Down

0 comments on commit 75bfd13

Please sign in to comment.