[PyQt] Can't get QCheckBox to work in a QTableView

Chris Dunscombe cdunscombe at yahoo.com
Mon Nov 26 18:46:30 GMT 2007


Andreas,

Thanks very much for your help. I'm going to take the item based approach using QStandardItemModel
and not use my own model. I've now got the Checkbox part to work by setting the item to be
checkable using item().setCheckable(True).

Thanks again,

Chris
--- Andreas Pakulat <apaku at gmx.de> wrote:

> On 26.11.07 04:13:24, Chris Dunscombe wrote:
> > --- Andreas Pakulat <apaku at gmx.de> wrote:
> > 
> > > On 23.11.07 09:04:56, Chris Dunscombe wrote:
> > > > Hi,
> > > > 
> > > > I'm trying to have a checkable column plus label with other columns in a table. I can't
> use
> > > > QTableWidget as one of the other columns is a ComboBox. After much trying, googling and
> > > reading of
> > > > Mark's excellent new book I just can't get it to work. I'm clearly doing something wrong
> > > > 
> > > > Main problem is that the label doesn't display unless it's being clicked. Also I can't
> check
> > > the
> > > > checkbox unless I've previously double-clicked in the area where the label is.
> > > 
> > > Why do you try to use a QCheckBox in the first place? Just return the
> > > Qt::IsUserCheckable flag in flags() and react to the Qt::CheckStateRole
> > > in data() for the apropriate column. Then the view itself will add a
> > > checkbox to the column and display the text from data(). Works like a
> > > charm.
> > > 
> > > Anyway, some comments...
> > > 
> > > > class myModel(QStandardItemModel):
> > > 
> > > This is wrong, you're misuing the standard item model. Please read its
> > > API docs, its usually not needed to subclass it, you only need to create
> > > QStandardItem's for the various cells in your model and set them
> > > checkable if they should be checkable.
> > > 
> > > If you want to write your own model, because you have some custom/legacy
> > > data format use QAbstractTableModel as base (when its tabular data) or
> > > QAbstractItemModel (if its tree-like data).
> >
> > Thanks very much for your reply. I've tried again, using QAbstractTableModel and without a
> custom
> > ItemDelegate, but I still can't get it to work.
> > 
> > Do I need to use a custom ItemDelegate given I don't need a QCheckBox but use
> > Qt.ItemIsUserCheckable from flags()?
> 
> No you don't need that, AFAIK. To make sure check the QItemDelegate
> code, it should handle the UserCheckable Role.
> 
> > I just can't seem to get my head around this. If you could include some code as a simple
> example
> > that would be greatly appreciated.
> 
> There's already quite some code included in PyQt, namely
> examples/interview
> 
> Another thing to use to check your model does the right thing (and thus
> eliminate one source of potential problems) is using the modeltest that
> was developed and opensourced by Benjamin Meyer on labs.trolltech.com.
> There's a PyQt version included in the PyQt tarball under
> contrib/modeltest/ including instructions how to use it.
>  
> >         self.setModel(self.model)
> >         # Add the single column
> >         self.model.insertColumn(0)
> >
> >         # Add the rows
> >         for dummy in range(numRows):
> >             self.model.insertRow(0)
> 
> This is still kinda wrong. You have to decide wether you want to use an
> itembased approach where you create items for the model and insert them
> into the model (in which case you don't create your own model class but
> use QStandardItemModel) or wether you have some existing data which
> should be made available through a Qt model interface. In the latter
> case you write your model and give it the data like you did in your
> code. There's no need to insert any data into the model then as it'll
> alreay have data from your dataObj.
> 
> >     def data(self, index, role=Qt.DisplayRole):
> 
> There's tons of sanity checks missing here, check that the index is
> valid, check that the row and column of the index doesn't exceed your
> data objects size and also check that the role is a role you can handle.
> 
> >         if role == Qt.CheckStateRole:
> >             if self.dataObj[index.row()] == 0:
> >                 return QVariant(Qt.Unchecked)
> >             else:
> >                 return QVariant(Qt.Checked)
> 
> You also need to return something for the display role, I doubt a view
> will display anything unless your provide either some text or an icon.
> 
> >     def setData(self, index, value, role):
> 
> Same thing here about the sanity checks and handling of the role.
> >             if value == Qt.Checked:
> >                 self.dataObj[index.row()] = 1
> >             else:
> >                 self.dataObj[index.row()] = 0
> >         else:
> >             print "Set data with no CheckStateRole"
> > 
> >         self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),index, index)
> 
> You should only emit the signal when you actually changed the data.
> 
> >     def flags(self, index):
> >         if index.column() == 0:
> >             return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsUserCheckable |
> > Qt.ItemIsSelectable
> >         else:
> >             return Qt.ItemIsEnabled
> > 
> > myList = []
> > myList.append(0)
> > myList.append(1)
> 
> A dict is a better datatype for a table-like model.
> 
> Andreas
> 
> -- 
> Expect the worst, it's the least you can do.
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
> 



      ____________________________________________________________________________________
Get easy, one-click access to your favorites. 
Make Yahoo! your homepage.
http://www.yahoo.com/r/hs 


More information about the PyQt mailing list