From f5b4fd595e90167e6a70bdfb5510e3dac3c6df9a Mon Sep 17 00:00:00 2001 From: Johnson Le Date: Fri, 22 Nov 2024 13:43:52 -0800 Subject: [PATCH] Selection Bug fix after deletion (GUI to Table) --- pymapmanager/interface2/core/search_widget.py | 55 +++++++++---------- .../interface2/runInterfaceJohnson.py | 30 +++++++++- .../interface2/stackWidgets/stackWidget2.py | 2 +- tests/interface/test_stack_widgets.py | 14 +++-- 4 files changed, 62 insertions(+), 39 deletions(-) diff --git a/pymapmanager/interface2/core/search_widget.py b/pymapmanager/interface2/core/search_widget.py index c55cd92..3db561e 100644 --- a/pymapmanager/interface2/core/search_widget.py +++ b/pymapmanager/interface2/core/search_widget.py @@ -63,20 +63,14 @@ def filterAcceptsRow(self, sourceRow, sourceParent): # logger.error(f' sourceParent:{sourceParent} {type(sourceParent)}') # super().filterAcceptsRow(sourceRow) - - # Specific column is already set in QTableView - # and comparison value + # Specific column is already set in QTableView and comparison value # row, column, qmodelindx filterCol = self.filterKeyColumn() - # logger.error(f' filterCol:{filterCol}') - valIndex = self.sourceModel().index(sourceRow, filterCol, sourceParent) - # yearIndex = self.sourceModel().index(sourceRow, 1, sourceParent) role = QtCore.Qt.DisplayRole val = self.sourceModel().data(valIndex, role) - # year = self.sourceModel().data(yearIndex) # logger.info(f'self.nameRegExp pattern: {self.nameRegExp.pattern()}, valIndex: {valIndex}, val: {val}') # logger.info(f'ComparisonValue: {self.currentComparisonValue}, ComparisonSymbol : {self.currentComparisonSymbol}') @@ -169,11 +163,11 @@ def headerData(self, section, orientation, role): # logger.info(f'visualRowIdx:{visualRowIdx} _ret:{_ret}') # return _ret - def data(self, index, role): + def data(self, index, role) -> str: """ data(const QModelIndex &index, int role = Qt::DisplayRole) - Returns the data stored under the given role for the item referred to by the index. + Returns the data stored under the given role for the item referred to by the index. (in str form) """ # print("data", self.rowCount(None)) # print("role: ", type(role)) @@ -415,7 +409,6 @@ def updateComparisonValue(self, newValue): # How do we get this working with the current filtering? # New problem, how do we reset the rows? when comparison is done - def setColList(self): """ Acquires all column names in dataframe and places them in a list """ @@ -499,18 +492,9 @@ def getSelectedRows(self): selectedIndexes.append(self.df.index[selectedRow]) return selectedIndexes - - # indexes = [] - # for index in selection.indexes(): - # if index.column() == 0: - # indexes.append(index.data()) - - # # logger.info(f'indexes: {indexes} ') #data {item.data()} - # return indexes # def keyPressEvent(self, event : QtGui.QKeyEvent): # super().keyPressEvent(event) - # # abb on_selectionChanged is not using its params # # self.on_selectionChanged(None) @@ -586,13 +570,8 @@ def on_double_clicked(self, item): def doSearch(self, searchStr): """Receive new word and filters df accordingly """ - self.currentSearchStr = searchStr - # self.df = self.df.reset_index() - # print("df", self.df) - if self.currentColName != "": - # print("we have a col Name") colIdx = self.df.columns.get_loc(self.currentColName) self.proxyModel.setFilterKeyColumn(colIdx) # self.proxyModel.setFilterFixedString(searchStr) @@ -617,10 +596,6 @@ def deleteRow(self, index = None): # self.model.removeRows(index, 1) self.update_data() - # def setData(self, row, col, value): - # # self.model.setData(row, col, value) - # self.update_data() - @contextmanager def _blockSlotsManager(self): try: @@ -633,7 +608,7 @@ def _blockSlotsManager(self): raise e finally: self._blockSignalSelectionChanged = False - + def _selectRow(self, rowList): """Programatically select rows of model via mySelectionModel @@ -660,10 +635,16 @@ def _selectRow(self, rowList): for _idx, rowIdx in enumerate(rowList): # abb already row label # abb 20241121 -->> this is not getting the correct row + logger.info(f"rowIdx in _selectRow{rowIdx}") + + modelIndex = self.findModelIndex(column=0, value=rowIdx) # column = 0, assuming index is always first column + logger.info(f"modelIdx in _selectRow {modelIndex}") + + # find the correct model.index get a spine Index(rowIndex) # 2nd argument is column # here we default to zero since we will select the entire row regardless - modelIndex = self.model.index(rowIdx, 0) + # modelIndex = self.model.index(rowIdx, 0) proxyIndex = self.proxyModel.mapFromSource(modelIndex) logger.info(f' modelIndex.row():{modelIndex.row()} proxyIndex.row():{proxyIndex.row()}') @@ -686,4 +667,18 @@ def _selectNewRow(self): logger.info(f"_selectNewRow rowIdx: {rowIdx-1}") self._selectRow(rowIdx-1) + def findModelIndex(self, column, value): + """ Given a column (index) and value (selected Spine Index) return the model index so + that we can programatically select it + """ + role = QtCore.Qt.DisplayRole + for row in range(self.model.rowCount(None)): + index = self.model.index(row, column) + modelData = int(self.model.data(index, role)) + # logger.info(f"index {index} modelData! {modelData}") + if modelData == value: + return index + + logger.info("Model Index not found") + return QModelIndex() # Return an invalid index if not found diff --git a/pymapmanager/interface2/runInterfaceJohnson.py b/pymapmanager/interface2/runInterfaceJohnson.py index cd9c8ac..f848abf 100644 --- a/pymapmanager/interface2/runInterfaceJohnson.py +++ b/pymapmanager/interface2/runInterfaceJohnson.py @@ -6,8 +6,15 @@ # from qtpy import QtWidgets from pymapmanager.interface2 import PyMapManagerApp +from pymapmanager.interface2.stackWidgets.base.mmWidget2 import pmmEvent, pmmEventType from stackWidgets import stackWidget2 +from pymapmanager.interface2.stackWidgets.event.spineEvent import (AddSpineEvent, + DeleteSpineEvent, + MoveSpineEvent, + UndoSpineEvent, + SelectSpine) + def _old_AddRandomColumns(df): import numpy as np # remember, never do this in production code @@ -57,7 +64,24 @@ def run(): # sw2.getStack().getPointAnnotations().intializeIsBad() # sw2.getStack().getPointAnnotations().intializeUserType() # sw2.forceRefresh() - sw2.zoomToPointAnnotation(5, isAlt=True) + # sw2.zoomToPointAnnotation(1, isAlt=True) + + sw2.zoomToPointAnnotation(1, isAlt=True) + spineID = 1 + deleteEvent = DeleteSpineEvent(sw2, spineID) + # deleteEvent = DeleteSpineEvent(sw2) + # deleteEvent.addDeleteSpine(spineID) + # sw2.deletedEvent(deleteEvent) + # sw2.emitEvent(deleteEvent, blockSlots=False) + sw2.slot_pmmEvent(deleteEvent) + + + # _pmmEvent = pmmEvent(pmmEventType.delete, sw2) + # _pmmEvent.setValue("pointSelection", [1]) + # sw2.emitEvent(_pmmEvent) + # sw2.slot_pmmEvent(_pmmEvent) + + # sw2.deletedEvent() # sw2.runPlugin('Scatter Plot', inDock=True) @@ -173,13 +197,13 @@ def testingProgrammaticRunClose(): sys.exit(app.exec_()) if __name__ == '__main__': - # run() + run() # run2() # run3() # run4() # run5() # runFirstWindow() - testingOpenClose() + # testingOpenClose() # runPoochFileDirectly() # testingProgrammaticRunClose() # run2_tif() \ No newline at end of file diff --git a/pymapmanager/interface2/stackWidgets/stackWidget2.py b/pymapmanager/interface2/stackWidgets/stackWidget2.py index 5359a12..299526e 100644 --- a/pymapmanager/interface2/stackWidgets/stackWidget2.py +++ b/pymapmanager/interface2/stackWidgets/stackWidget2.py @@ -1250,7 +1250,7 @@ def closePlugin(self, pluginKey: tuple): Args: pluginKey : tuple (plugin Name, id: numbered instance of plugin) - plugin Name: of the plugin, defined as static member vraible in mmWidget + plugin Name: of the plugin, defined as static member variable in mmWidget show: bool If True then immediately show the widget """ diff --git a/tests/interface/test_stack_widgets.py b/tests/interface/test_stack_widgets.py index 22a9815..b639bab 100644 --- a/tests/interface/test_stack_widgets.py +++ b/tests/interface/test_stack_widgets.py @@ -57,6 +57,7 @@ def test_plugins_empty(qtbot, qapp): open_plugins(stackWidgetWindow, stackPluginDict, selection = False) +@pytest.mark.skip(reason="not currently testing") def test_plugins(qtbot, qapp): """Run all plugins through a number of different tests. """ @@ -111,7 +112,9 @@ def close_plugins(stackWidgetWindow, stackPluginDict): else: # close plugin/ stackWidget # stackWidgetWindow.close() - stackWidgetWindow.closePlugin(pluginName) + # stackWidgetWindow.closePlugin(pluginName) + firstPluginWindow = (pluginName, 1) + stackWidgetWindow.closePlugin(firstPluginWindow) def make_and_cancel_selection(stackWidgetWindow): # Make a selection @@ -145,19 +148,20 @@ def manipulate_spines(stackWidgetWindow): y = 222 z = 31 moveEvent = MoveSpineEvent(stackWidgetWindow, spineID=items, x=x, y=y, z=z) - stackWidgetWindow.moveAnnotationEvent(moveEvent) + # stackWidgetWindow.moveAnnotationEvent(moveEvent) + stackWidgetWindow.slot_pmmEvent(moveEvent) # Add Spine x = 600 y = 230 z = 30 addEvent = AddSpineEvent(stackWidgetWindow, x, y, z) - stackWidgetWindow.addedEvent(addEvent) + stackWidgetWindow.slot_pmmEvent(addEvent) # Delete Spine spineID = 6 deleteEvent = DeleteSpineEvent(stackWidgetWindow, spineID) - stackWidgetWindow.deletedEvent(addEvent) + stackWidgetWindow.slot_pmmEvent(deleteEvent) # TODO: Undo and Redo # Note: Robert said that redo is not working correctly @@ -165,7 +169,7 @@ def manipulate_spines(stackWidgetWindow): undoEvent1 = deleteEvent # Undo delete spine undoDeleteEvent = UndoSpineEvent(stackWidgetWindow, undoEvent1) - stackWidgetWindow.undoEvent(undoDeleteEvent) + stackWidgetWindow.slot_pmmEvent(undoDeleteEvent) # TODO: # Load in with tif ch 1