2012-06-06 6 views
1

트리 선택을 특정 열로 제한하려고합니다.QT QItemSelectionModel은 열을 무시합니까?

저는 델리게이트를 사용하여 열 단위의 비헤이비어, 편집자 등을 만드는 데 많은 도움을주고 있습니다. 이벤트 나 비슷한 것을 차단하여 델리게이트에서 어떻게 든 할 수 있기를 바랬습니다. 문제는 확장 된 선택을 모방 한 전적으로 사용자 지정 솔루션을 만들어야한다고 생각합니다.

그러나 많은 검색과 아주 적은 예제를 사용한 후에는 트리보기에서 사용자 지정 QItemSelectionModel을 원한다고 들립니다. 이 가정이 맞습니까?

확장 선택 모드를 사용하지만 특정 열에없는 경우 선택을 무시하거나 되돌릴 수있는 사용자 지정 QItemSelectionModel은 어떻게 만듭니 까? 즉, 다른 열을 클릭해도 선택 항목이 변경되지 않습니다 (선택하거나 선택 취소하지 말아야 함).

일단 선택 모델을 추가하면이를 추가하는 방법을 알고 있습니다. 파생 클래스를 구현하는 데 도움이 필요합니다 (연결된 신호로 수행 할 수있는 경우가 아니면).

저는 파이썬을 사용하고 있지만 도움이 될 것입니다.

, 감사합니다

[편집 :] 내가이 비슷한 질문을 발견. http://lists.qt.nokia.com/pipermail/qt-interest/2010-September/027647.html

"서브 클래스 QItemSelectionModel을하고 원하는 동작을 위해 선택 방법을 모두 구현할 단지의 부분을 무시 범위가 0보다 큰 범위 ... 또는 항목을 선택할 수 없게 만들려면 flags()를 다시 구현하십시오. 부작용이 있는지 알고 싶다면 을 입력하십시오. "

내가 내 QTreeWidgetItem에 플래그를 재 구현했지만,이 호출되지있어 결코 :

def flags(self, index): 
    print index.column() 
    return super(DDOutlinerBaseItem, self).flags(index) 
+0

데이터에 사용자 지정 모델을 사용합니까? 선택할 수있는 물체는 모델에 의해 제어됩니다. 'QAbstractItemModel :: flags()'(http://qt-project.org/doc/qt-4.8/qabstractitemmodel.html # flags)와'Qt :: ItemFlags' (http://qt-project.org/doc/qt-4.8/qt.html#ItemFlag-enum)를 참조하십시오. – leemes

+0

코멘트 주셔서 감사합니다. 나는 QTreeWidgetItems를 사용하고있다. 나는'flags'가 인덱스 당 읽을 수 있지만, 플래그를 설정하는 유일한 방법은 QTreeWidgetItem.setFlags()의 항목 레벨에있는 것을 볼 수 있습니다. 나는 함수를 오버라이드하려고 시도했지만 호출 된 적이 없다 : def flags (self, index) : print index.column() super (DDOutlinerBaseItem, self) .flags (index)' – Rafe

+0

Qt의 모델은 어쨌든 있습니다 :) 선택 모델의 C++ 소스 코드를 살펴 보았습니다. 'select()'가 호출 될 때마다 관련 데이터 모델을 보지 않습니다. QAbstractItemView.selectionBehaviour (http://qt-project.org/doc/qt-4.8/qabstractitemview.html#SelectionBehavior-enum)의 값으로 연주 해보십시오. 어쩌면 사용자가 무언가를 선택하려고 할 때 모델을 보는 것은 뷰 (선택 모델 아님) 일 수 있습니다. 이것이 도움이되지 않는다면 Qt 뷰의 선택 처리에 대해 충분히 알지 못하기 때문에 다른 사람의 대답을 기다려야합니다. : – leemes

답변

4

이론적으로 다음 조정이 필요합니다.

위의 솔루션은 오버로드 된 메서드 이름을 명확하게하기 위해 두 개의 별도의 방법과 @pyqtSlot 데코레이터를 사용할 수 있습니다

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

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

이 메소드 구현의 특정 클래스의 인스턴스를 확인 할 필요가 피할 수 있습니다.

0

첫 번째 흥미로운 점은 파이썬이 방법을 오버로드 할 수 없기 때문에, 내 선택 방법은 단순히 두 번 호출 할 것이다, 인수 0의 각 유형마다 한 번씩. 기본 설정뿐만 아니라이를 설명하기위한 예제가 있습니다. 나는이을 내 대리인 시스템에 결정을 위임 할 계획 내 최종 구현에서

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) 

: 내 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) 

라고 일반적이고 이론 상으로는 원하는 인덱스를 동적으로 무시할 수 있습니다.

관련 문제