def parent(self, index): if not index.isValid(): return QtCore.QModelIndex() child_item = index.internalPointer() parent_item = child_item.parent() if parent_item is None or parent_item == self.rootItem: return QtCore.QModelIndex() return self.createIndex(parent_item.row(), 0, parent_item)
def _readViewSettings(self, reset=False): """ Reads the persistent program settings :param reset: If True, the program resets to its default settings """ pos = QtCore.QPoint(20 * self._instance_nr, 20 * self._instance_nr) window_size = QtCore.QSize(1024, 700) details_button_idx = 0 header = self.obj_tree.header() header_restored = False if reset: logger.debug("Resetting persistent view settings") else: logger.debug("Reading view settings for window: {:d}".format( self._instance_nr)) settings = get_qsettings() settings.beginGroup(self._settings_group_name('view')) pos = settings.value("main_window/pos", pos) window_size = settings.value("main_window/size", window_size) details_button_idx = int( settings.value("details_button_idx", details_button_idx)) splitter_state = settings.value("central_splitter/state") if splitter_state: self.central_splitter.restoreState(splitter_state) header_restored = self.obj_tree.read_view_settings( 'table/header_state', settings, reset) settings.endGroup() if not header_restored: column_sizes = [col.width for col in self._attr_cols] column_visible = [col.col_visible for col in self._attr_cols] for idx, size in enumerate(column_sizes): if size > 0: # Just in case header.resizeSection(idx, size) for idx, visible in enumerate(column_visible): self.obj_tree.toggle_column_actions_group.actions( )[idx].setChecked(visible) self.resize(window_size) self.move(pos) button = self.button_group.button(details_button_idx) if button is not None: button.setChecked(True)
def canFetchMore(self, parent=None): parent = QtCore.QModelIndex() if parent is None else parent if parent.column() > 0: return 0 else: result = not self.treeItem(parent).children_fetched # logger.debug("canFetchMore: {} = {}".format(parent, result)) return result
def rowCount(self, parent=None): parent = QtCore.QModelIndex() if parent is None else parent if parent.column() > 0: # This is taken from the PyQt simpletreemodel example. return 0 else: return self.treeItem(parent).child_count()
def resizeEvent(self, event): """ Resizes the details box if present (i.e. when 'Show Details' button was clicked) """ result = super(ResizeDetailsMessageBox, self).resizeEvent(event) details_box = self.findChild(QtWidgets.QTextEdit) if details_box is not None: #details_box.setFixedSize(details_box.sizeHint()) details_box.setFixedSize( QtCore.QSize(self.detailsBoxWidth, self.detailBoxHeight)) return result
def index(self, row, column, parent=None): if parent is None: logger.debug("parent is None") parent = QtCore.QModelIndex() parentItem = self.treeItem(parent) if not self.hasIndex(row, column, parent): logger.debug("hasIndex is False: ({}, {}) {!r}".format( row, column, parentItem)) #logger.warn("Parent index model: {!r} != {!r}".format(parent.model(), self)) return QtCore.QModelIndex() childItem = parentItem.child(row) #logger.debug(" {}".format(childItem.obj_path)) if childItem: return self.createIndex(row, column, childItem) else: logger.warn("no childItem") return QtCore.QModelIndex()
def fetchMore(self, parent=None): """ Fetches the children given the model index of a parent node. Adds the children to the parent. """ parent = QtCore.QModelIndex() if parent is None else parent if parent.column() > 0: return parent_item = self.treeItem(parent) if parent_item.children_fetched: return tree_items = self._fetchObjectChildren(parent_item.obj, parent_item.obj_path) self.beginInsertRows(parent, 0, len(tree_items) - 1) for tree_item in tree_items: parent_item.append_child(tree_item) parent_item.children_fetched = True self.endInsertRows()
def rootIndex(self): # TODO: needed? """ The index that returns the root element (same as an invalid index). """ return QtCore.QModelIndex()
def hasChildren(self, parent=None): parent = QtCore.QModelIndex() if parent is None else parent if parent.column() > 0: return 0 else: return self.treeItem(parent).has_children
def get_qsettings(): """ Creates a QSettings object for this application. We do not set the application and organization in the QApplication object to prevent side-effects. """ return QtCore.QSettings("titusjan.nl", PROGRAM_NAME)
def __init__( self, obj, name='', attribute_columns=DEFAULT_ATTR_COLS, attribute_details=DEFAULT_ATTR_DETAILS, show_callable_attributes=None, # None uses value from QSettings show_special_attributes=None, # None uses value from QSettings auto_refresh=None, # None uses value from QSettings refresh_rate=None, # None uses value from QSettings reset=False): """ Constructor :param obj: any Python object or variable :param name: name of the object as it will appear in the root node :param attribute_columns: list of AttributeColumn objects that define which columns are present in the table and their defaults :param attribute_details: list of AttributeDetails objects that define which attributes can be selected in the details pane. :param show_callable_attributes: if True rows where the 'is attribute' and 'is callable' columns are both True, are displayed. Otherwise they are hidden. :param show_special_attributes: if True rows where the 'is attribute' is True and the object name starts and ends with two underscores, are displayed. Otherwise they are hidden. :param auto_refresh: If True, the contents refershes itsef every <refresh_rate> seconds. :param refresh_rate: number of seconds between automatic refreshes. Default = 2 . :param reset: If true the persistent settings, such as column widths, are reset. """ super(ObjectBrowser, self).__init__() self._instance_nr = self._add_instance() # Model self._attr_cols = attribute_columns self._attr_details = attribute_details (self._auto_refresh, self._refresh_rate, show_callable_attributes, show_special_attributes) = \ self._readModelSettings(reset = reset, auto_refresh = auto_refresh, refresh_rate = refresh_rate, show_callable_attributes= show_callable_attributes, show_special_attributes = show_special_attributes) self._tree_model = TreeModel(obj, name, attr_cols=self._attr_cols) self._proxy_tree_model = TreeProxyModel( show_callable_attributes=show_callable_attributes, show_special_attributes=show_special_attributes) self._proxy_tree_model.setSourceModel(self._tree_model) #self._proxy_tree_model.setSortRole(RegistryTableModel.SORT_ROLE) self._proxy_tree_model.setDynamicSortFilter(True) #self._proxy_tree_model.setSortCaseSensitivity(Qt.CaseInsensitive) # Views self._setup_actions() self._setup_menu() self._setup_views() self.setWindowTitle("{} - {}".format(PROGRAM_NAME, name)) self._readViewSettings(reset=reset) assert self._refresh_rate > 0, "refresh_rate must be > 0. Got: {}".format( self._refresh_rate) self._refresh_timer = QtCore.QTimer(self) self._refresh_timer.setInterval(self._refresh_rate * 1000) self._refresh_timer.timeout.connect(self.refresh) # Update views with model self.toggle_special_attribute_action.setChecked( show_special_attributes) self.toggle_callable_action.setChecked(show_callable_attributes) self.toggle_auto_refresh_action.setChecked(self._auto_refresh) # Select first row so that a hidden root node will not be selected. first_row_index = self._proxy_tree_model.firstItemIndex() self.obj_tree.setCurrentIndex(first_row_index) if self._tree_model.inspectedNodeIsVisible: self.obj_tree.expand(first_row_index)