class DockGridManager(QDockWidget): def __init__(self, voxel_widget, voxel_grid, parent=None): # Initializes the UI - this is pretty standard super(DockGridManager, self).__init__(parent) self.ui = Ui_DockTableManager() self.ui.setupUi(self) self.setWindowTitle( QApplication.translate("DockGridManager", "Grids Manager", None, QApplication.UnicodeUTF8) ) # Setting the protected members: self._voxel_widget = voxel_widget # GLWidget - Refreshes the OpenGL area self._voxel_grid = voxel_grid # VoxelGrid - Modify the number and order of rows. # Setting the custom model for the QTableView self.model = VoxelGridModel( self._voxel_widget, self._voxel_grid ) self.ui.table.setModel( self.model ) # Setting the custom delegate for the QTableView self.ui.table.setItemDelegate( VoxelGridDelegate() ) # Customizing some QTableView properties self.ui.table.verticalHeader().hide() self.ui.table.resizeColumnsToContents() self.ui.table.setFocusPolicy( Qt.NoFocus ) self.ui.table.setSelectionBehavior(QAbstractItemView.SelectRows) ## # Event that inserts a new row to the table. # If a row is selected, inserts before that row. def table_record_add(self): selection = self.ui.table.selectionModel() index = selection.currentIndex(); if( selection.hasSelection() ): self.model.insertRow(index.row(), index.parent() ) else: self.model.insertRow(-1, index.parent() ) ## # Event that removes a row from the table. One or more rows must be selected or else, this won't have any effect. def table_record_delete(self): selection = self.ui.table.selectionModel() remove_sucess = True # We use a while and a custom flag here to know when we are done. The flag indicates when the user tried to remove an unremovable row. while( selection.hasSelection() and remove_sucess ): index = selection.currentIndex() remove_sucess = self.model.removeRow( index.row(), index.parent() ) ## # This method moves an row Uo (moving_up = True) or Down (moving_up = False) in the grid. def _table_record_move(self, moving_up = True ): # If nothing is selected, then there is nothing to move. selection = self.ui.table.selectionModel() if( not selection.hasSelection() ): return index = selection.currentIndex(); grid_planes = self._voxel_grid.get_grid_planes_list() # Checks to see if the new position is valid, or else, returns. if( ( moving_up and index.row() < 1 ) or ( not moving_up and index.row() >= len( grid_planes )-1 ) ): return # The swap_index is where the current row will go (be swapped with). swap_index = self.model.index( index.row() + ( -1 if moving_up else 1 ), index.column() ) # Now, in case we are moving up, we exchange the indexs, bexause the method dataChanged goes from topLeft to BottomRight # Ex. index = (3,x), swap_index = (2,x). dataChanged( (3,x), (2,x) ) -> (3,x) is no the top most index, thats why we swap it. if( moving_up ): index, swap_index = swap_index, index # Here, we swap the values in the list of "GridPlane"s. It kind of doesn't matters the order of the swap grid_planes[index.row()], grid_planes[swap_index.row()] = grid_planes[swap_index.row()], grid_planes[index.row()] # And here, that magic dataChanged event =] self.model.dataChanged.emit( index, swap_index ) # Here, we update the selection and the current index, so that the user can keep clicking on the move button # until the row goes where he wants it. selection.select( swap_index, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows ) selection.setCurrentIndex( index if moving_up else swap_index, QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows ) ## # Event that moves the selected row one row Up def table_record_move_up(self): self._table_record_move( moving_up = True ) ## # Event that moves the selected row one row Down def table_record_move_down(self): self._table_record_move( moving_up = False )