[Qt5-feedback] Add internalVariant to QModelIndex

Stephen Kelly steveire at gmail.com
Fri Jul 15 21:01:11 CEST 2011


Charley Bay wrote:

> Please forgive the long post --  I believe Stephen understands my issue,
> and I want to respond with sufficient detail that clarifies as best I can.
> 

I'll end the long email habit here and cut off large parts of this one.

Parts of your response didn't make sense to me, but we could back and forth 
about it endlessly, so I'll leave it all out.

> A "summary statement" is that I'd like to merely expose my (fairly
> common-and-typical) model-of-containment-of-different-types to the GUI,
> not write an adapter infrastructure that I can "mount" my model into, for
> the purpose of exposing to the GUI.

> class MyBookNode {
>   public:
>     void* book_or_chapter_or_paragraph_;
>     enum { BOOK, CHAPTER, PARAGRAPH } enum_type_;
> };

(from below):

>> What is the actual problem you're trying to solve? 
> Goal:  Containment models can be *exposed* to the model/view
> infrastructure
> without requiring an adapter (synchronization) layer.  I assert this is a
> "common" case.  IMHO, that adapter/synchronization layer is prohibitively
> expensive (we don't use Qt model/view unless we absolutely must, because
> the cost is so high).

> For my specific concerns, it's too hard to maintain the synchronization
> layer (lots of code, tedious to synchronize). 

So the main problem is that you consider it prohibitively expensive in 
developmer and maintiner time to implement the adapter pattern using a Node 
of some sort.

I don't agree, and it seems to me that the whole point of QAIM is to define 
an interface for that adapter so that your model can be used with the rest 
of Qt (in views, comboboxes etc). You're trying to avoid doing exactly what 
the class is supposed to be doing, which is implementing the adapter.

I agree it's not perfect, but adding an enum isn't the right fix. There are 
several model-related efforts underway in Qt (eg in QML) or abandoned 
(itemviews-ng). I suggest to seek them out and see if they solve the problem 
better for you and work on making it 'the new way' if possible.

> For the API, we would add one (overloaded) function where we could create
> a QModelIndex with *both* the void* and the enum:
> 
> QModelIndex QAbstractItemModel::createIndex(int row, int column, void*
> ptr, quint32 user_num);

That also would mean that tables would have to do something like

createIndex(row, column, 0, MyBookType);

That 0 is not nice and can't be overloaded away.

> Performance should be pretty much the same (copy construction is copying
> void* and int, rather than just void*).

I don't know that it ould be the same... There is also a concern of 
additional memory needs. How much extra would this cost on a 64 bit system? 
Is there padding? (I don't know).

You would need to create benchmarks, but really I don't see this happening 
anyway in Qt5 to be honest. Apart from the QStandardItem-like API which you 
could implement as described below, you could look into itemviews-ng which 
is C++ template and iterator based. You could try to revive it and make it 
the new way of doing models.


>> It sounds like the QStandardItem API would suit you better. I know the
>> QStandardItemModel API has its own problems, but let's just consider
>> QStandardItem. You can create a QStandardItem and then do something like
>>
>> item.setData(QVariant::fromValue(myBook));
>>
>> and then later
>>
>> QVariant var = item.data();
>>
>> if (var.type() == BookType) ...
>> else if (var.type() == ChapterType) ...
>> else if (var.type() == ParagraphType) ...
>>
> 
> That may be a reasonable alternative adapter layer for my
> containment-models.  I see similar value-semantics-synchronization
> efforts,
> though:  I need the QVariant to contain *both* the void*-and-enum, or a
> reference to a MyBookNode that contains both. 

No, QVariant::type() is exactly what you want for your enum. 
QVariant::value() is your data. 

QVariant var = item.data();

if (var.type() == BookType)
    MyBook book = var.value<MyBook>();
    // ... Use book.
else if (var.type() == ChapterType)
    MyChapter chapter = var.value<MyChapter>();
    // ... Use chapter
else if (var.type() == ParagraphType) ...
    

> <...> but it would still be a work-around that required significant
> adapter code.

You would only need to write an adapter one last time and wrap it in your 
new API. 


All the best,

Steve.




More information about the Qt5-feedback mailing list