def index(model, row, column, parent=QtCore.QModelIndex()): """ Qt Override Returns: the index of the item in the model specified by the given row, column and parent index. When reimplementing this function in a subclass, call createIndex() to generate model indexes that other components can use to refer to items in your model. NOTE: Object must be specified to sort delegates. """ # model.lazy_checks() if not parent.isValid(): # This is a top level == 0 index # logger.info('[model.index] ROOT: row=%r, col=%r' % (row, column)) if row >= model.root_node.get_num_children(): return QtCore.QModelIndex() # import traceback # traceback.print_stack() node = model.root_node[row] if model.col_level_list[column] != node.get_level(): return QtCore.QModelIndex() qtindex = model.createIndex(row, column, object=node) return qtindex else: # This is a child level > 0 index parent_node = parent.internalPointer() node = parent_node[row] if ut.USE_ASSERT: assert isinstance(parent_node, _atn.TreeNode), type(parent_node) assert isinstance(node, _atn.TreeNode), type(node) return model.createIndex(row, column, object=node)
def parent(model, qindex): """ A common convention used in models that expose tree data structures is that only items in the first column have children. For that case, when reimplementing this function in a subclass the column of the returned QModelIndex would be 0. When reimplementing this function in a subclass, be careful to avoid calling QModelIndex member functions, such as QModelIndex.parent(), since indexes belonging to your model will simply call your implementation, leading to infinite recursion. FIXME: seems to segfault in here https://riverbankcomputing.com/pipermail/pyqt/2016-February/036977.html https://gist.github.com/estan/c051d1f798c4c46caa7d Returns: the parent of the model item with the given index. If the item has no parent, an invalid QModelIndex is returned. """ # model.lazy_checks() if qindex.isValid(): try: node = qindex.internalPointer() # <HACK> # A segfault happens in isinstance when updating rows? if not isinstance(node, _atn.TreeNode): logger.info( 'WARNING: tried to access parent of %r type object' % type(node)) return QtCore.QModelIndex() # assert node.__dict__, "node.__dict__=%r" % node.__dict__ # </HACK> parent_node = node.get_parent() parent_id = parent_node.get_id() if parent_id == -1 or parent_id is None: return QtCore.QModelIndex() row = parent_node.get_row() col = model.col_level_list.index(parent_node.get_level()) return model.createIndex(row, col, parent_node) except Exception as ex: import utool with utool.embed_on_exception_context: qindex_rc = (qindex.row(), qindex.column()) # NOQA ut.printex( ex, 'failed to do parenty things', keys=['qindex_rc', 'model.name'], tb=True, ) import utool utool.embed() raise return QtCore.QModelIndex()
def index(self, row, col, parent=QtCore.QModelIndex()): """Returns the index of the item in the model specified by the given row, column and parent index.""" if parent.isValid() and parent.column() != 0: return QtCore.QModelIndex() parentPref = self.index2Pref(parent) childPref = parentPref.qt_get_child(row) if childPref: return self.createIndex(row, col, childPref) else: return QtCore.QModelIndex()
def parent(self, index=None): """Returns the parent of the model item with the given index. If the item has no parent, an invalid QModelIndex is returned.""" if index is None: # Overload with QtCore.QObject.parent() return QtCore.QObject.parent(self) if not index.isValid(): return QtCore.QModelIndex() nodePref = self.index2Pref(index) parentPref = nodePref.qt_get_parent() if parentPref == self.rootPref: return QtCore.QModelIndex() return self.createIndex(parentPref.qt_parents_index_of_me(), 0, parentPref)
def fetchMore(model, parent=QtCore.QModelIndex()): """ Fetches any available data for the items with the parent specified by the parent index. Reimplement this if you are populating your model incrementally. The default implementation does nothing. """ if parent is None: return if parent.isValid(): # Check if we are at a leaf node node = parent.internalPointer() if node.get_num_children() == 0: return remainder = model.num_rows_total - model.num_rows_loaded if model.batch_size is None: num_fetching = remainder else: num_fetching = min(model.batch_size, remainder) if VERBOSE_MODEL: logger.info('Fetching %r more %s' % (num_fetching, model.name)) idx1 = model.num_rows_total idx2 = model.num_rows_total + num_fetching - 1 # model.beginInsertRows(QtCore.QModelIndex(), idx1, idx2) model.beginInsertRows(parent, idx1, idx2) model.num_rows_loaded += num_fetching # logger.info('model.num_rows_total = %r' % (model.num_rows_total,)) # logger.info('model.num_rows_loaded = %r' % (model.num_rows_loaded,)) model.endInsertRows() if VERBOSE_MODEL: logger.info('Fetched %r/%r rows' % (model.num_rows_loaded, model.num_rows_total))
def canFetchMore(model, parent=QtCore.QModelIndex()): """ Returns true if there is more data available for parent; otherwise returns false. The default implementation always returns false. If canFetchMore() returns true, the fetchMore() function should be called. This is the behavior of QAbstractItemView, for example. References: http://doc.qt.io/qt-5/qtwidgets-itemviews-fetchmore-example.html # Extend this to work well with QTreeViews http://blog.tjwakeham.com/lazy-loading-pyqt-data-models/ http://stackoverflow.com/questions/38506808/pyqt4-force-view-to-fetchmore-from """ if parent is None: return if parent.isValid(): # Check if we are at a leaf node node = parent.internalPointer() if node.get_num_children() == 0: return # if node.get_level() == len(model.col_level_list): # return # logger.info('model.num_rows_total = %r' % (model.num_rows_total,)) # logger.info('model.num_rows_loaded = %r' % (model.num_rows_loaded,)) if model.num_rows_total is not None: if model.num_rows_loaded < model.num_rows_total: if VERBOSE_MODEL: logger.info('canFetchMore %s? -- Yes' % (model.name, )) return True if VERBOSE_MODEL: logger.info('canFetchMore %s? -- No' % (model.name, )) return False
def index2Pref(self, index=QtCore.QModelIndex()): """ Internal helper method """ if index.isValid(): item = index.internalPointer() if item: return item return self.rootPref
def proxy_to_source(self, row, col, parent=QtCore.QModelIndex()): source_model = self.sourceModel() source_cols = source_model.columnCount(parent=parent) r, c, p = row, col, parent r2 = int(math.floor(c / source_cols)) + (r * self._nd) c2 = c % source_cols p2 = p return r2, c2, p2
def source_to_proxy(self, row, col, parent=QtCore.QModelIndex()): source_model = self.sourceModel() source_cols = source_model.columnCount(parent=parent) r, c, p = row, col, parent r2 = int(math.floor(r / self._nd)) c2 = ((r % self._nd) * source_cols) + c p2 = p return r2, c2, p2
def mapFromSource(self, sourceIndex): """ returns index into proxy model """ if sourceIndex is None: return None if sourceIndex.isValid(): r2, c2, p2 = self.source_to_proxy(sourceIndex.row(), sourceIndex.column(), sourceIndex.parent()) proxyIndex = self.index(r2, c2, p2) else: proxyIndex = QtCore.QModelIndex() return proxyIndex
def mapToSource(self, proxyIndex): """ returns index into original model """ if proxyIndex is None: return None if proxyIndex.isValid(): r2, c2, p2 = self.proxy_to_source(proxyIndex.row(), proxyIndex.column()) sourceIndex = self.sourceModel().index( r2, c2, parent=p2 ) # self.sourceModel().root_node[r2] else: sourceIndex = QtCore.QModelIndex() return sourceIndex
def rowCount(model, parent=QtCore.QModelIndex()): """ Qt Override """ # model.lazy_checks() if not parent.isValid(): # Root row count if len(model.level_index_list) == 0: return 0 return model.num_rows_loaded # nRows = len(model.level_index_list) # # logger.info('* nRows=%r' % nRows) # return nRows else: node = parent.internalPointer() nRows = node.get_num_children() # logger.info('+ nRows=%r' % nRows) return nRows
def _get_adjacent_qtindex(model, qtindex=QtCore.QModelIndex(), offset=1): # check qtindex if qtindex is None or not qtindex.isValid(): return None node = qtindex.internalPointer() # check node try: if ut.USE_ASSERT: assert isinstance(node, _atn.TreeNode), type(node) except AssertionError as ex: ut.printex(ex, key_list=['node'], pad_stdout=True) raise # get node parent try: node_parent = node.get_parent() except Exception as ex: ut.printex(ex, key_list=['node'], reraise=False, pad_stdout=True) raise # parent_node check if node_parent is None: logger.info('[model._get_adjacent_qtindex] node_parent is None!') return None # Offset to find the next qtindex next_index = node_parent.child_index(node) + offset nChildren = node_parent.get_num_children() # check next index validitiy if next_index >= 0 and next_index < nChildren: next_node = node_parent.get_child(next_index) next_level = next_node.get_level() col = model.col_level_list.index(next_level) row = next_node.get_row() # Create qtindex for the adjacent note parent_qtindex = model.parent(qtindex) next_qtindex = model.index(row, col, parent_qtindex) return next_qtindex else: # There is no adjacent node return None
def _get_row_id(model, qtindex=QtCore.QModelIndex()): """ returns the id (specified by iders i.e. an wbia rowid) from qtindex """ if qtindex is not None and qtindex.isValid(): node = qtindex.internalPointer() if ut.USE_ASSERT: try: assert isinstance(node, _atn.TreeNode), 'type(node)=%r, node=%r' % ( type(node), node, ) except AssertionError as ex: ut.printex( ex, 'error in _get_row_id', keys=['model', 'qtindex', 'node'] ) raise try: id_ = node.get_id() except AttributeError as ex: ut.printex(ex, key_list=['node', 'model', 'qtindex']) raise return id_
def columnCount(self, parent=QtCore.QModelIndex()): source_cols = self.sourceModel().columnCount(parent=parent) cols = self._nd * source_cols # print('StripeProxyModel.columnCount(): %r %r' % (source_cols, cols)) return int(cols)
def rowCount(self, parent=QtCore.QModelIndex()): sourceParent = self.mapToSource(parent) source_rows = self.sourceModel().rowCount(parent=sourceParent) rows = math.ceil(source_rows / self._nd) # print('StripeProxyModel.rowCount(): %r %r' % (source_rows, rows)) return int(rows)
def index(self, row, col, parent=QtCore.QModelIndex()): if (row, col) != (-1, -1): proxyIndex = self.createIndex(row, col, parent) else: proxyIndex = QtCore.QModelIndex() return proxyIndex
def index(model, row, column, parent=QtCore.QModelIndex()): """ Qt Override """ return model.createIndex(row, column)
def source_to_proxy(self, row, col, parent=QtCore.QModelIndex()): r2, c2, p2 = row, col, parent return r2, c2, p2
def columnCount(model, parent=QtCore.QModelIndex()): """ Qt Override """ return len(model.col_name_list)
def rowCount(model, parent=QtCore.QModelIndex()): """ Qt Override """ return len(model.row_sortx)
def columnCount(model, parent=QtCore.QModelIndex()): """ Qt Override """ # FOR NOW THE COLUMN COUNT IS CONSTANT # model.lazy_checks() return len(model.col_name_list)
def columnCount(self, parent=QtCore.QModelIndex()): parentPref = self.index2Pref(parent) return parentPref.qt_col_count()
def rowCount(self, parent=QtCore.QModelIndex()): parentPref = self.index2Pref(parent) return parentPref.qt_row_count()