第一个有趣的事情是,由于 Python 不能重载方法,我的 select 方法似乎只是被调用了两次,参数 0 中的每种类型调用一次。这里有一个示例来说明这一点以及基本设置。我的 QTreeWidget 的树称为“树”(self.tree
)
# in __init__ of my QTreeWidget:
sel_model = ColumnSelectionModel(self.tree.model())
self.tree.setSelectionModel(sel_model)
class ColumnSelectionModel(QtGui.QItemSelectionModel):
def select(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)))
if isinstance(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)
elif isinstance(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)
这似乎解决了我的问题:
class ColumnSelectionModel(QtGui.QItemSelectionModel):
def __init__(self, model):
super(ColumnSelectionModel, self).__init__(model)
self.selectable_columns = [0]
""" Set the columns that are allowed to be selected """
def select(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
"""
if isinstance(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]
if not index.column() in self.selectable_columns:
return
elif isinstance(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
if not index.column() in self.selectable_columns:
return
else: # Just in case
raise Exception("Unexpected type for arg 0: '%s'" % type(selection))
# Fall through. Select as normal
super(ColumnSelectionModel, self).select(selection, selectionFlags)
在我的最终实现中,我计划将决定委托给我的委托系统,使其具有通用性,并且理论上能够动态地忽略我想要的任何索引。