Skip to content Skip to sidebar Skip to footer

Qt Qitemselectionmodel To Ignore Columns?

I am trying to restrict selection of a tree to a particular column. I am using delegates heavily to create custom per-item-per-column behaviors, editors, etc. I was hoping I could

Solution 1:

The following adjustment should work, in theory.

The above solution could use two separate methods and @pyqtSlot decorators to disambiguate the overloaded method names:

@pyqtSlot(QModelIndex, QItemSelectionModel.SelectionFlags)
  def select(self, index, command):
    # ...

@pyqtSlot(QItemSelection, QItemSelectionModel.SelectionFlags)
  def select(self, selection, command):
    #...

This avoids the need to check for instances of certain classes in the method implementations.

Solution 2:

The first interesting thing is that since Python can't overload a method, my select method seems to simply be called twice, once for each type in argument 0. Here is an example to illustrate this as well as the basic setup. My QTreeWidget's tree it called 'tree' (self.tree)

# in __init__ of my QTreeWidget:
    sel_model = ColumnSelectionModel(self.tree.model())
    self.tree.setSelectionModel(sel_model)

classColumnSelectionModel(QtGui.QItemSelectionModel):
    defselect(self, selection, selectionFlags):
    """
    Runs both QItemSelectionModel.select methods::

        1. select(QtCore.QModelIndex, QItemSelectionModel.SelectionFlags)
        2. select(QtGui.QItemSelection, QItemSelectionModel.SelectionFlags)

    The first seems to run on mouse down and mouse up.
    The second seems to run on mouse down, up and drag
    """print("select(%s,  %s)" % (type(selection), type(selectionFlags)))

    ifisinstance(selection, QtGui.QItemSelection):
        infos = []
        for index in selection.indexes():
            infos.append(("index=%s row=%s column=%s" 
                                    % (index, index.row(), index.column())))

        print", ".join(infos)
    elifisinstance(selection, QtCore.QModelIndex):
        index = selection
        print("index=%s row=%s column=%s" % (index, index.row(), index.column()))
    else:
        raise Exception("Unexpected type for arg 0: '%s'" % type(selection))

    super(ColumnSelectionModel, self).select(selection, selectionFlags)

This appears to solve my problem:

classColumnSelectionModel(QtGui.QItemSelectionModel):
    def__init__(self, model):
        super(ColumnSelectionModel, self).__init__(model)

        self.selectable_columns = [0]
        """ Set the columns that are allowed to be selected """defselect(self, selection, selectionFlags):
        """
        Ignores any selection changes if an item is not in one of the columns
        in the self.selectable_columns list.

        Is run by both QItemSelectionModel.select methods::

            1. select(QtCore.QModelIndex, QItemSelectionModel.SelectionFlags)
            2. select(QtGui.QItemSelection, QItemSelectionModel.SelectionFlags)

        The first seems to run on mouse down and mouse up.
        The second seems to run on mouse down, up and drag
        """ifisinstance(selection, QtGui.QItemSelection):
            # This is the overload with the QItemSelection passed to arg 0# Loop over all the items and if any are not in selectable_columns#   ignore this event. This works because it is run for every change#   so the offending selection index will always be the newest
            indexes = selection.indexes()
            for i in xrange(len(indexes)):
                index = indexes[i]
                ifnot index.column() in self.selectable_columns:
                    returnelifisinstance(selection, QtCore.QModelIndex):
            # This is the overload with the QModelIndex passed to arg 0# If this index isn't in selectable_columns, just ignore this event
            index = selection
            ifnot index.column() in self.selectable_columns:
                returnelse:  # Just in caseraise Exception("Unexpected type for arg 0: '%s'" % type(selection))

        # Fall through. Select as normalsuper(ColumnSelectionModel, self).select(selection, selectionFlags)

In my final implementation, I plan to delegate the decision to my delegate system, making this generic and, in theory, able to dynamically ignore any index I want.

Post a Comment for "Qt Qitemselectionmodel To Ignore Columns?"