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()
Example #5
0
    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
Example #10
0
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)