[Interest] Issue with QSortFilterProxyModel and Delegate

David Boosalis david.boosalis at gmail.com
Thu May 10 14:05:07 CEST 2012


André, your a rock star !!! I did as you suggested and "wahhla, bingo,
bango" -  it all works.  Thanks a lot for taking the time to answer my
question.

-David


On Thu, May 10, 2012 at 4:52 AM, André Somers <andre at familiesomers.nl>wrote:

> Op 10-5-2012 13:45, David Boosalis schreef:
> > Hope someone can help me here.  I have a QTableView for which I use my
> > own QSortFilterProxyModel and own Delegate which is based on
> > QStyledItemDelegate.  My issue is in the Delegates::paintEvent()
> > I get core dumps if I have the following (Not using a proxy filter it
> > works by the way):
> >
> > void DataDelegate::paint(QPainter *painter,
> >              const QStyleOptionViewItem &option,
> >              const QModelIndex &index) const
> > {
> >   QStandardItem *item = 0;
> >   if (!index.isValid()) {
> >     qWarning() << "Invalid index" << __FILE__ << __LINE__;
> >     return;
> >   }
> >  QStyledItemDelegate::paint(painter,option,index);
> >  QStandardItemModel *m = (QStandardItemModel *) index.model();
> >   bool isWatched    =  index.data(Qt::UserRole+4).toBool();
> >   if ( (isWatched) && (index.column() == 0))  {
> >     item = (QStandardItem *) m->itemFromIndex(index);  //
> > <--------------- CORE DUMPS HERE------------------
> >     if (!item) {
> >       return;
> >     }
> >    .// continue to do some custom painting...
> >
> ------------------------------------------------------------------------------------------------------------------------
> >
> > Now if I do something like this:
> > void DataDelegate::paint(QPainter *painter,
> >              const QStyleOptionViewItem &option,
> >              const QModelIndex &proxyIndex) const
> > {
> >   QStandardItem *item = 0;
> >   if (!proxyIndex.isValid()) {
> >     qWarning() << "Invalid proxy index" << __FILE__ << __LINE__;
> >     return;
> >   }
> >   QStyledItemDelegate::paint(painter,option,proxyIndex);
> >   if (!proxyFilter) {  // store in Delegate class and is pointer to a
> > class derived from QSortFilterProxyModel
> >     qWarning() << "Invalid model for data delegate" << __FILE__ <<
> > __LINE__;
> >     return;
> >   }
> >  QModelIndex index = proxyFilter->mapToSource(proxyIndex);
> >   if (!index.isValid()) {
> >     // qWarning() << "Invalid index for data delegate" << __FILE__ <<
> > __LINE__;
> >     return;
> >   }
> >   QStandardItemModel *m = (QStandardItemModel *) index.model();
> >   bool isWatched    =  index.data(Qt::UserRole+4).toBool();
> >   if ( (isWatched) && (index.column() == 0))  {
> >     item = (QStandardItem *) m->itemFromIndex(index); //
> >     if (!item) {
> >       return;
> >     }
> >    // continue to do some custom painting....
> >
> >
> > This works, with the following ugly exception.  I get a lot of run
> > time warnings
> > " QSortFilterProxy Model: index from wrong model passed to mapToSource"
> >
> > Despite these warnings I doI get my custom painting to occur.  I would
> > like to figure out a way to do it right so that I do not get thousands
> > of these warning messages at runitme.
> >
> > Any suggestions on how to properly do a Delegate::paint() on a
> > QTableView with a custom QSortFilterProxyModel is greatly appreciated.
> >
> >
> > -David
> That seems completely logical to me. As you found out, you need to check
> any pointer you get back to see if it is not 0 before you dereference
> it. In your case, your issue is that you're mixing indexes from your
> proxy model and your source model. Don't do that. They can be mapped to
> each other, but only by the proxy model itself.
>
> Instead of trying to get a QStandardItem*, why don't use simply use the
> actual data exposed throught the model API itself? Any data you need for
> rendering should be available through the data() or flags() method.
> Nothing more. What you are doing is tightly binding your delegate to the
> model that feeds the data to the view. That will break down as soon as
> you decide to change the model (or, as in your case, put a proxy between
> the model and the view). Instead, you should limit yourself to the
> interface you get from QAbstractItemModel. That is the only thing your
> delegate should know about.
>
> André
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20120510/109f1afc/attachment.html>


More information about the Interest mailing list