Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt4 Local Directory view with option to select folders

I know how to make a simple QTreeView() with a QDirModel (or QFileSystemModel) to show the files/folders in the system but I want to add a checkbox next to each of them so the user can select some of the folders/files on his system. Obviously, I also need to know which ones he has chosen. Any hints?

basically something like this...

enter image description here

Below is a sample code that makes a directory view but without the checkboxes.

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_())
like image 557
Kiarash Avatar asked Mar 12 '13 05:03

Kiarash


1 Answers

You can subclass QDirModel, and reimplement data(index,role) method, where you should check, if role is QtCore.Qt.CheckStateRole. If it is, you should return either QtCore.Qt.Checked or QtCore.Qt.Unchecked. Also, you need to reimplement setData method as well, to handle user checks/unchecks, and flags to return QtCore.Qt.ItemIsUserCheckable flag, which enables user checking/unchecking. I.e.:

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)

Then you use this class instead of QDirModel:

model = CheckableDirModel()
tree = QtGui.QTreeView()
tree.setModel(model)
like image 119
user2155932 Avatar answered Oct 11 '22 15:10

user2155932