2013-03-12 10 views
6

Ich weiß, wie man ein einfaches QTreeView() mit einem QDirModel (oder QFileSystemModel) erstellt, um die Dateien/Ordner im System anzuzeigen, aber ich möchte ein Kontrollkästchen neben jedem von ihnen hinzufügen So kann der Benutzer einige der Ordner/Dateien auf seinem System auswählen. Natürlich muss ich auch wissen, welche er ausgewählt hat. Irgendwelche Hinweise?PyQt4 Local Directory-Ansicht mit Option zum Auswählen von Ordnern

im Grunde so etwas wie dieses ...

enter image description here

Unten ist ein Beispielcode, der eine Verzeichnisansicht aber ohne die Checkbox macht.

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_()) 

Antwort

5

Sie können QDirModel Unterklasse und data(index,role) Methode neu implementieren, wo Sie sollten überprüfen, ob roleQtCore.Qt.CheckStateRole ist. Wenn dies der Fall ist, sollten Sie entweder QtCore.Qt.Checked oder QtCore.Qt.Unchecked zurückgeben. Außerdem müssen Sie auch die Methode neu implementieren, um Benutzer zu überprüfen/deaktivieren, und flags, um QtCore.Qt.ItemIsUserCheckable Flag zurückgeben, die Benutzer aktivieren/deaktivieren ermöglicht. Dh:

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) 

Dann nutzen Sie diese Klasse statt QDirModel:

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

Dies funktioniert nur gut, aber wissen Sie, wie es so zu modifizieren, wenn man auf C klickt: dann werden alle Unterkategorien erhalten geklickt und wenn man klickte auf eine Unterkategorie C: wurde ein Punkt (halb geprüft)? – Kiarash

+0

@Kiarash Sie sollten Kinder- und Elternindizes von 'index' in' setData' entsprechend ändern. Um einen Child-Index zu erhalten, verwenden Sie 'QModelIndex.child'. Um einen übergeordneten Index zu erhalten, verwenden Sie 'QModelIndex.parent'. Um eine Anzahl von Kindern mit einem bestimmten Index zu erhalten, sollten Sie 'QDirModel.rowCount' verwenden. Siehe [dies] (http://pyqt.sourceforge.net/Docs/PyQt4/qmodelindex.html) und [dies] (http://pyqt.sourceforge.net/Docs/PyQt4/qabstractitemmodel.html#rowCount) – user2155932

+0

So in der setData habe ich einfach folgendes hinzugefügt: für i in range (self.rowCount (index)): self.setData (index.child (i, 0), value, role) ABER es ist so langsam, wenn man auf C: klickt. Irgendwelche Ideen, wie man das löst? – Kiarash

Verwandte Themen