最初の興味深い点は、Pythonはメソッドをオーバーロードできないため、私のselectメソッドは引数0のタイプごとに1回ずつ、単純に2回呼び出されるように見えることです。これと基本的な設定を説明する例を次に示します。私の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)
最終的な実装では、決定を委任システムに委任することを計画しています。これにより、これが一般的になり、理論的には、必要なインデックスを動的に無視できるようになります。