[Kde-bindings] playground/bindings/kimono

Richard Dale richard.j.dale at gmail.com
Mon Mar 5 21:16:57 UTC 2007


On Sunday 04 March 2007, Arno Rehn wrote:
> Am Samstag, 3. März 2007 schrieb Arno Rehn:
> > SVN commit 638799 by arnorehn:
> >
> > * Added QModelIndex.InternalPointer() and
> > QAbstractItemModel.CreateIndex() * Added simpletreemodel example (doesn't
> > fully work yet)
>
> Uhm, does anyone have an idea, why we can't select any sub-items in the
> simpletreemodel example? I don't know what goes wrong with the
> CreateIndex() function, it keeps saying
> Can't select indexes from different model or with different parents.
> I looked at how it is done in qtruby, but I don't really understand how
> it's working there...
> Maybe someone could explain it to me?
I added some debugging to the QItemSelectionModel code:

void QItemSelection::select(const QModelIndex &topLeft, const QModelIndex
&bottomRight)
{
    if (!topLeft.isValid() || !bottomRight.isValid())
        return;

    if ((topLeft.model() != bottomRight.model())
        || topLeft.parent() != bottomRight.parent()) {
        qWarning("Can't select indexes from different model or with different
parents");
        qWarning("topLeft.model: %p bottomRight.model: %p",
            topLeft.model(),bottomRight.model() );
        qWarning("topLeft.parent().row(): %d topLeft.parent().column(): %d
bottomRight.parent().row(): %d bottomRight.parent().column(): %d",
            topLeft.parent().row(), topLeft.parent().column(),
bottomRight.parent().row(), bottomRight.parent().column());
        qWarning("topLeft.parent().internalPointer(): %p
bottomRight.parent().internalPointer(): %p",
            topLeft.parent().internalPointer(),
bottomRight.parent().internalPointer() );
        qWarning("topLeft.parent().model(): %p
bottomRight.parent().model(): %p",
            topLeft.parent().model(), bottomRight.parent().model() );
        return;
    }

And it printed this:

Can't select indexes from different model or with different parents
topLeft.model: 0x84e2230 bottomRight.model: 0x84e2230
topLeft.parent().row(): 5 topLeft.parent().column(): 0
bottomRight.parent().row(): 5 bottomRight.parent().column(): 0
topLeft.parent().internalPointer(): 0x7db3
bottomRight.parent().internalPointer(): 0x7d8b
topLeft.parent().model(): 0x84e2230 bottomRight.parent().model(): 0x84e2230

So the 'internalPointer' has a different value even when the underlying
instance is the same. That's because QAbstractItemModel.CreateIndex()
allocates a new GCHandle every time, which will have different values. The
reason it works in QtRuby is because the internalPointer is a Ruby VALUE that
is  the same for every createIndex call.

                protected QModelIndex CreateIndex(int row, int column,
object ptr) {
                        IntPtr ret =
AbstractItemModelCreateIndex((IntPtr) GCHandle.Alloc(this),

 row, column, (IntPtr) GCHandle.Alloc(ptr));
                        return (QModelIndex) ((GCHandle) ret).Target;
                }

So it's actually quite tricky to fix. Also in QtRuby the garbage collection
isn't quite right and the QModelIndex() stuff can cause crashes because the
Ruby runtime doesn't know anything about the 'internalPointer' that is
stashed away.

-- Richard



More information about the Kde-bindings mailing list