2013-03-12 10 views
6

Wiem, jak wykonać proste QTreeView() z QDirModel (lub QFileSystemModel), aby wyświetlić pliki/foldery w systemie, ale chcę dodać pole wyboru przy każdym z nich aby użytkownik mógł wybrać niektóre foldery/pliki w swoim systemie. Oczywiście, muszę też wiedzieć, które zostały wybrane. Jakieś wskazówki?Widok lokalnego katalogu PyQt4 z opcją wyboru folderów

zasadzie coś takiego ...

enter image description here

Poniżej znajduje się przykładowy kod, który sprawia, że ​​widok katalogu ale bez wyboru.

from PyQt4 import QtGui 

if __name__ == '__main__': 

    import sys 

    app = QtGui.QApplication(sys.argv) 

    model = QtGui.QDirModel() 
    tree = QtGui.QTreeView() 
    tree.setModel(model) 

    tree.setAnimated(False) 
    tree.setIndentation(20) 
    tree.setSortingEnabled(True) 

    tree.setWindowTitle("Dir View") 
    tree.resize(640, 480) 
    tree.show() 

    sys.exit(app.exec_()) 

Odpowiedz

5

Można podklasy QDirModel i reimplement data(index,role) metodę, gdzie należy sprawdzić, czy role jest QtCore.Qt.CheckStateRole. Jeśli tak, powinieneś zwrócić: QtCore.Qt.Checked lub QtCore.Qt.Unchecked. Trzeba również ponownie zastosować metodę setData, aby obsłużyć sprawdzanie/odznaczanie przez użytkownika, i flags, aby zwrócić flagę QtCore.Qt.ItemIsUserCheckable, która umożliwia użytkownikowi sprawdzenie/odznaczenie. Tj:

class CheckableDirModel(QtGui.QDirModel): 
def __init__(self, parent=None): 
    QtGui.QDirModel.__init__(self, None) 
    self.checks = {} 

def data(self, index, role=QtCore.Qt.DisplayRole): 
    if role != QtCore.Qt.CheckStateRole: 
     return QtGui.QDirModel.data(self, index, role) 
    else: 
     if index.column() == 0: 
      return self.checkState(index) 

def flags(self, index): 
    return QtGui.QDirModel.flags(self, index) | QtCore.Qt.ItemIsUserCheckable 

def checkState(self, index): 
    if index in self.checks: 
     return self.checks[index] 
    else: 
     return QtCore.Qt.Unchecked 

def setData(self, index, value, role): 
    if (role == QtCore.Qt.CheckStateRole and index.column() == 0): 
     self.checks[index] = value 
     self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) 
     return True 

    return QtGui.QDirModel.setData(self, index, value, role) 

Następnie użyć tej klasy zamiast QDirModel:

model = CheckableDirModel() 
tree = QtGui.QTreeView() 
tree.setModel(model) 
+0

Działa to dobrze, ale czy wiesz, jak go zmodyfikować tak, gdy ktoś kliknie na C: to wszystkie podkategorie dostać kliknął i kiedy jeden kliknął podkategorię C: stał się kropką (na wpół sprawdzone)? – Kiarash

+0

@ Kiarash Powinieneś odpowiednio zmienić indeksy dzieci i rodziców 'index' w' setData'. Aby uzyskać indeks potomny, użyj 'QModelIndex.child'. Aby uzyskać indeks macierzysty, użyj 'QModelIndex.parent'. Aby uzyskać liczbę dzieci z danego indeksu, powinieneś użyć 'QDirModel.rowCount'. Zobacz [to] (http://pyqt.sourceforge.net/Docs/PyQt4/qmodelindex.html) i [this] (http://pyqt.sourceforge.net/Docs/PyQt4/qabstractitemmodel.html#rowCount) – user2155932

+0

w setData, po prostu dodałem to: dla i w zakresie (self.rowCount (indeks)): self.setData (index.child (i, 0), wartość, rola) ALE jest tak wolno, jeśli kliknie się na C:. Wszelkie pomysły, jak to rozwiązać? – Kiarash