PDA

View Full Version : QItemEditorFactory and custom Model



maximAL
23rd November 2007, 12:10
Hi,
i tried to define my own delegate editor for a custom Tree model used with a standard QTreeView.

seup is like this:


QItemEditorFactory *factory = new QItemEditorFactory();
QItemEditorCreatorBase *lineEditorCreator =
new QStandardItemEditorCreator<LineEditorCreator>();
factory->registerEditor(QVariant::String, lineEditorCreator);
QItemEditorFactory::setDefaultFactory(factory);

SceneModel model("test.xml");

QTreeView view;
view.setModel(&model);
view.show();
this is the delegate (yes, it's only for testing):

class LineEditorCreator : public QLineEdit
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText USER true)

public:
LineEditorCreator(QWidget *widget = 0):
QLineEdit(widget)
{
};

QString text() const
{
return QLineEdit::text();
};

void setText(QString text)
{
QLineEdit::setText(text);
};

};

i can also add the code for the model, but to my understanding it shouldn't interfere with the delegate.
without the custom delegate, editing works fine (so, yes, items are editable), with the delegate just nothing happens (and it's functions aren't called at all).

for testing purpose, i also tried with a standard QTreeWidget and the delegate works just fine there.

are there any special additions to be made to an model, so it supports the delegate?

wysota
23rd November 2007, 13:28
You did not provide code of the delegate but of the widget used for editing - don't mix those two. The problem here might be that you register the editor for QString and by default the model doesn't contain strings (if it's empty, for example). In your case I'd suggest to subclass the delegate class and reimplement QAbstractItemDelegate::createEditor() to return your widget instead of QLineEdit.

maximAL
23rd November 2007, 13:50
The problem here might be that you register the editor for QString and by default the model doesn't contain strings (if it's empty, for example).
could you elaborate on that? the model uses custom SceneItem objects storing the actual data (strictly following the official QT tutorial on creating customs models). the data is definitely handled as QVariant::String (read: QString).


In your case I'd suggest to subclass the delegate class and reimplement QAbstractItemDelegate::createEditor() to return your widget instead of QLineEdit.
yes, i tried this and it works. nevertheless, providing editors via the factory would simply be the more elegant way for my purpose, so i'd really like to get it working.

btw: i tried this approach:


// no default factory!
//QItemEditorFactory::setDefaultFactory(factory);
...
QItemDelegate delegate;
delegate.setItemEditorFactory(factory);
...
view.setItemDelegate(&delegate);
this has no effect. now, the standard editor instead of my own one is used again.

jpn
23rd November 2007, 15:34
I second Wysota. Most likely the problem is that model's data() does not return a QString for Qt::EditRole for an empty index. Therefore, when you start editing an empty cell, you'll get an editor for QVariant::Invalid which is the default editor, a QLineEdit (or QExpandingLineEdit to be exact). You can get past the problem by simply registering your custom editor for QVariant::Invalid too (if that's what you want):


factory->registerEditor(QVariant::String, lineEditorCreator);
factory->registerEditor(QVariant::Invalid, lineEditorCreator); // <---

maximAL
23rd November 2007, 15:45
it also doesn't work with cells containing data.
but indeed, it works when setting the editor for QVariant::Invalid -> for all cells! so for some reason editing passes around invalid qvariants. maybe indeed a bug in my model, hmm...

edit: so for all who care to know what the mistake was:
my model's data(..) function returned an empty QVariant() for any index role besided DisplayRole

maximAL
26th November 2007, 14:45
so, after digging deeper into the whole issue, i'm struggling now with the mime stuff for drag and drop and i'm really starting to wonder if i'm not completely heading the wrong direction (because it becomes so overly complicated to do basic things).

thats what i want to achive basically:
i have a tree model and view displaying the contents of an XML file.
the data has to be represented if different ways, eg. for some strings i might just need a plain lineedit, for others a combobox filled with standard values etc., also doubles might need different validators etc.
my approach was now to build custom types for all elements and provide specialized editors for each type.
now i ran in quite a mess with all that qvariant stuff, casting my own data from and to it, mime data handling and what not.

another approach i could imagine is just using standard qvariant types and use custom item roles to identifiy the type of an element and provide different editors via a delegate->createEditor.

the first approach seems to be the intended way to go but is quiet complicated, the second one is pretty straight forward, but will also result in some not-so-elegant code (big switch - case blocks instead of decoupled editor classes etc.).

maybe someone could share his experiences on that. i don't want to use the straight forward method just to realize it would have been worth getting into the more complicated stuff later one.