2013-03-12 9 views
6

So come creare un semplice QTreeView() con un QDirModel (o QFileSystemModel) per mostrare i file/le cartelle nel sistema ma voglio aggiungere una casella di controllo accanto a ciascuno di essi quindi l'utente può selezionare alcune cartelle/file sul suo sistema. Ovviamente, ho anche bisogno di sapere quali hanno scelto. Qualche suggerimento?PyQt4 Visualizzazione directory locale con opzione per selezionare le cartelle

fondamentalmente qualcosa di simile ...

enter image description here

seguito è riportato un codice di esempio che rende una vista directory, ma senza le caselle di controllo.

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

risposta

5

È possibile creare una sottoclasse QDirModel, e reimplementare data(index,role) metodo, in cui si dovrebbe verificare, se role è QtCore.Qt.CheckStateRole. In tal caso, è necessario restituire QtCore.Qt.Checked o QtCore.Qt.Unchecked. Inoltre, è necessario reimplementare il metodo setData, per gestire i controlli utente/deselezionare e flags per restituire il flag QtCore.Qt.ItemIsUserCheckable, che consente all'utente di selezionare/deselezionare. Vale a dire:

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) 

Quindi si utilizza questa classe, invece di QDirModel:

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

Questo funziona bene, ma sai come modificarlo in modo che quando si clicca su C: allora tutte le sottocategorie ottenere cliccato e quando uno ha cliccato su una sottocategoria C: diventa un punto (mezzo-controllato)? – Kiarash

+0

@Kiarash Dovresti cambiare gli indici figli e parent di 'index' in' setData' di conseguenza. Per ottenere un indice secondario, utilizzare 'QModelIndex.child'. Per ottenere un indice padre, utilizzare 'QModelIndex.parent'. Per ottenere un numero di figli di un determinato indice si dovrebbe usare 'QDirModel.rowCount'. Vedi [this] (http://pyqt.sourceforge.net/Docs/PyQt4/qmodelindex.html) e [this] (http://pyqt.sourceforge.net/Docs/PyQt4/qabstractitemmodel.html#rowCount) – user2155932

+0

Quindi nel setData, ho semplicemente aggiunto questo: per i in range (self.rowCount (index)): self.setData (index.child (i, 0), value, role) MA è così lento se si fa clic su C:. Qualche idea di come si possa risolvere? – Kiarash

Problemi correlati