From ec37d1c411e69ff77c36c72f84729add124a7c3f Mon Sep 17 00:00:00 2001 From: Mika Fischer Date: Thu, 16 Jun 2011 20:17:33 +0200 Subject: [PATCH] Synchronize selections between Scene and TreeView (closes #18) --- sloth/annotations/model.py | 23 +++++++++++++++++++---- sloth/gui/annotationscene.py | 16 ++++++++++++++++ sloth/gui/labeltool.py | 5 +++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/sloth/annotations/model.py b/sloth/annotations/model.py index 1ce0687..36d3e35 100644 --- a/sloth/annotations/model.py +++ b/sloth/annotations/model.py @@ -1,7 +1,7 @@ """ The annotationmodel module contains the classes for the AnnotationModel. """ -from PyQt4.QtGui import QTreeView, QSortFilterProxyModel, QAbstractItemView +from PyQt4.QtGui import QTreeView, QItemSelection, QItemSelectionModel, QSortFilterProxyModel, QAbstractItemView from PyQt4.QtCore import QModelIndex, QPersistentModelIndex, QAbstractItemModel, QVariant, Qt, pyqtSignal import os.path import copy @@ -505,15 +505,17 @@ class AnnotationSortFilterProxyModel(QSortFilterProxyModel): ####################################################################################### class AnnotationTreeView(QTreeView): + selectedItemsChanged = pyqtSignal(object) + def __init__(self, parent=None): super(AnnotationTreeView, self).__init__(parent) self.setUniformRowHeights(True) - self.setSelectionMode(QTreeView.SingleSelection) + self.setSelectionMode(QTreeView.ExtendedSelection) self.setSelectionBehavior(QTreeView.SelectItems) self.setAllColumnsShowFocus(True) self.setAlternatingRowColors(True) - self.setEditTriggers(QAbstractItemView.SelectedClicked) + #self.setEditTriggers(QAbstractItemView.SelectedClicked) self.setSortingEnabled(True) self.expanded.connect(self.onExpanded) @@ -539,4 +541,17 @@ class AnnotationTreeView(QTreeView): def rowsInserted(self, index, start, end): QTreeView.rowsInserted(self, index, start, end) self.resizeColumns() -# self.setCurrentIndex(index.child(end, 0)) + + def setSelectedItems(self, items): + block = self.blockSignals(True) + sel = QItemSelection() + for item in items: + sel.merge(QItemSelection(item.index(), item.index()), QItemSelectionModel.SelectCurrent) + self.selectionModel().clear() + self.selectionModel().select(sel, QItemSelectionModel.Select) + self.blockSignals(block) + + def selectionChanged(self, selected, deselected): + items = [ self.model().itemFromIndex(index) for index in self.selectionModel().selectedIndexes()] + self.selectedItemsChanged.emit(items) + QTreeView.selectionChanged(self, selected, deselected) diff --git a/sloth/gui/annotationscene.py b/sloth/gui/annotationscene.py index 383bb56..c429e79 100644 --- a/sloth/gui/annotationscene.py +++ b/sloth/gui/annotationscene.py @@ -52,6 +52,7 @@ class AnnotationScene(QGraphicsScene): self.disconnect(self.model_, SIGNAL('rowsAboutToBeRemoved(QModelIndex,int,int)'), self.rowsAboutToBeRemoved) self.disconnect(self.model_, SIGNAL('rowsRemoved(QModelIndex,int,int)'), self.rowsRemoved) self.disconnect(self.model_, SIGNAL('modelReset()'), self.reset) + self.model_ = model # connect new signals @@ -178,6 +179,21 @@ class AnnotationScene(QGraphicsScene): # selection mode QGraphicsScene.mouseMoveEvent(self, event) + + def onSelectionChanged(self): + model_items = [item.modelItem() for item in self.selectedItems()] + self.labeltool_.treeview().setSelectedItems(model_items) + + def onSelectionChangedInTreeView(self, items): + block = self.blockSignals(True) + items = [self.itemFromIndex(item.index()) for item in items] + for item in self.items(): + item.setSelected(False) + for item in items: + if item is not None: + item.setSelected(True) + self.blockSignals(block) + # # key event handlers #______________________________________________________________________________________________________ diff --git a/sloth/gui/labeltool.py b/sloth/gui/labeltool.py index c6a431f..4b32688 100755 --- a/sloth/gui/labeltool.py +++ b/sloth/gui/labeltool.py @@ -47,6 +47,8 @@ class MainWindow(QMainWindow): self.setWindowTitle("%s - Unnamed[*]" % APP_NAME) self.treeview.setModel(self.labeltool.model()) self.scene.setModel(self.labeltool.model()) + self.selectionmodel = QItemSelectionModel(self.labeltool.model()) + self.treeview.setSelectionModel(self.selectionmodel) self.treeview.selectionModel().currentChanged.connect(self.labeltool.setCurrentImage) def onCurrentImageChanged(self, index): @@ -119,6 +121,9 @@ class MainWindow(QMainWindow): self.treeview.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) self.ui.dockInformation.setWidget(self.treeview) + self.scene.selectionChanged.connect(self.scene.onSelectionChanged) + self.treeview.selectedItemsChanged.connect(self.scene.onSelectionChangedInTreeView) + # Show the UI. It is important that this comes *after* the above # adding of custom widgets, especially the central widget. Otherwise the # dock widgets would be far to large.