[PyQt] Qtreeview/QDirmodel with check-boxes

Jon Noble jonnobleuk at gmail.com
Mon May 31 02:15:32 BST 2010


On Monday 31 May 2010 01:10:12 Jon Noble wrote:
> On Monday 31 May 2010 00:07:43 Jon Noble wrote:
> > Hi,
> > 
> > I'm trying to create a file-system tree-view with checkboxes yet i'm
> > having great difficulties on doing so.
> > 
> > I found a link
> > (http://lists.trolltech.com/qt-interest/2005-08/msg00516.html) but I'm
> > not really sure what the solution is. I've tried one solution which is
> > to use QDirModel.setData() but that makes no difference.
> > 
> > Here's a snippet of my code.
> > 
> >     def __fileview_setup(self):
> >         """
> >         Make the fileview the correct type
> >         """
> >         
> >         index = QModelIndex()
> >         dir_model = QDirModel()
> >         filters = QDir.AllDirs|QDir.Readable|QDir.NoDotAndDotDot
> >         dir_model.setData(index, Qt.Checked, Qt.CheckStateRole)
> >         dir_model.setFilter(filters)
> >         dir_model.setReadOnly(True)
> > 	
> > 	# self.collection_view is a QTreeView
> > 	
> >         self.collection_view.setModel(dir_model)
> >         self.collection_view.setColumnHidden(1, True)
> >         self.collection_view.setColumnHidden(2, True)
> >         self.collection_view.setColumnHidden(3, True)
> >         self.collection_view.expandToDepth(0)
> > 
> > The file-system view part works fine, just no checkboxes.
> > 
> > Any help would be greatly recieved, thanks.
> > 
> > Jon
> 
> Never mind. I found a useful link that helped me solve my issue
> http://www.qtcentre.org/threads/6957-QDirModel-QTreeView-and-checkable-item
> s
> 
> Whilst not knowing c++ and Qt (QSet and the c++ "?" was a bit of a
> bafflement) i'm able to create a filesystem tree with checkable
> directories. It seems to work well apart from you don't see the checked
> box until you move the mouse away from the checkbox. That's a bit strange.
> 
> Here's the code:
> 
> class MyQDirModel(QDirModel):
>     checked = []
> 
>     def data(self, index, role = Qt.DisplayRole):
> 
>         if index.isValid() and (index.column() == 0) and (role ==
> Qt.CheckStateRole):
>             # the item is checked only if we have stored its path
>             print MyQDirModel.checked, unicode(self.filePath(index))
>             if unicode(self.filePath(index)) in MyQDirModel.checked:
>                 return Qt.Checked
>             else:
>                 return Qt.Unchecked
> 
>         return QDirModel.data(self, index, role)
> 
>     def flags(self, index):
>         if (index.column() == 0): # make the first column checkable
>            return QDirModel.flags(self, index) | Qt.ItemIsUserCheckable
>         else:
>             return QDirModel.flags(self, index)
> 
>     def setData(self, index, value, role = Qt.EditRole):
>         if index.isValid() and (index.column() == 0) and role ==
> Qt.CheckStateRole:
>             # store checked paths, remove unchecked paths
>             if (value == Qt.Checked):
>                 MyQDirModel.checked.append(unicode(self.filePath(index)))
>                 return False
>             else:
>                 MyQDirModel.checked.remove(unicode(self.filePath(index)))
>                 return False
> 
>         else:
>             return QDirModel.setData(self, index, value, role);
> 
> 
> 
> I am interacting with it in another class and method:
> 
>     def __fileview_setup(self):
>         """
>         Make the fileview the correct type
>         """
> 
>         index = QModelIndex()
>         dir_model = MyQDirModel()
>         filters = QDir.AllDirs|QDir.Readable|QDir.NoDotAndDotDot
>         dir_model.setData(index, Qt.Checked, Qt.CheckStateRole)
>         dir_model.setFilter(filters)
>         dir_model.setReadOnly(True)
>         self.collection_view.setModel(dir_model)
>         self.collection_view.setColumnHidden(1, True)
>         self.collection_view.setColumnHidden(2, True)
>         self.collection_view.setColumnHidden(3, True)
>         self.collection_view.expandToDepth(0)
> 
> 
> 
> Hope this helps someone as PyQt4 documentation/examples are sparse out
> there in the internet.
> 
> Regards
> 
> Jon
Woops, those "return False"s were experiment's I forgot to change back. Also, 
converting to unicode isn't necessary.



class MyQDirModel(QDirModel):
    checked = []
        
    def data(self, index, role = Qt.DisplayRole):
        if index.isValid() and (index.column() == 0) and (role == 
Qt.CheckStateRole):
            # the item is checked only if we have stored its path
            if self.filePath(index) in MyQDirModel.checked:
                return Qt.Checked
            else:
                return Qt.Unchecked
                
        return QDirModel.data(self, index, role)        
        
    def flags(self, index):
        if index.column() == 0: # make the first column checkable
           return QDirModel.flags(self, index) | Qt.ItemIsUserCheckable
        else:
            return QDirModel.flags(self, index)            
        
    def setData(self, index, value, role = Qt.EditRole):
        if index.isValid() and (index.column() == 0) and role == 
Qt.CheckStateRole:
            # store checked paths, remove unchecked paths
            if (value == Qt.Checked):
                MyQDirModel.checked.append(self.filePath(index))
                return True
            else:
                MyQDirModel.checked.remove(self.filePath(index))
                return True
                
        else:
            return QDirModel.setData(self, index, value, role);


More information about the PyQt mailing list