PDA

View Full Version : QStyledItemDelegate and editor pointer



Nero
13th September 2010, 11:09
Hello,
I've a QStyledItemDelegate derived class for a custom delegate editor:


CheckBoxDelegate::CheckBoxDelegate(const QStringList &texts, QObject *parent)
: QStyledItemDelegate(parent), texts(texts)
{ }

QWidget *CheckBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &index) const
{
CheckBoxDelegateWidget *editor = new CheckBoxDelegateWidget(texts, parent);
...
return editor;
}
Now I want sizeHint() to return the CheckBoxDelegateWidget sizes, like this:

QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
return editor->sizeHint(); // what editor?
}
Where I can obtain the editor pointer? Why createEditor() doesn't let me do a local copy of the pointer?
Thank you.

tbscope
13th September 2010, 11:19
You can keep a map of the widgets or size hints for each model index.

Be sure to not delete the widget pointers yourself, the view will do that for you.

Nero
13th September 2010, 11:38
Thanks tbscope,
sorry I'm a C++ newcomer, createEditor() is const so I should not modify class variables, am I wrong?

tbscope
13th September 2010, 11:53
Actually there's no need at all to store the pointer of the widget or the size hint etc...

Just use the model index in the sizeHint to get the needed data.


QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
CheckBoxDelegateWidget *editor = new CheckBoxDelegateWidget(index.data(...));

return editor->sizeHint();
}

tbscope
13th September 2010, 14:07
Oops:


QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
CheckBoxDelegateWidget editor(index.data(...));

return editor.sizeHint();
}

Nero
13th September 2010, 14:21
No problem, I've already seen that. :)
Thank you.

The Storm
20th September 2010, 12:56
Hello,

Sorry for bumping the thread but after reading it all I still can't get what value to put to the index.data() to get the editor? Maybe I must set the data myself but if that is the case I can't because createEditor() gives me constant QModelIndex reference.

Any help will be appreciated.

Nero
20th September 2010, 13:46
You need to call the constructor of your custom widget, in my case:

CheckBoxDelegateWidget(const QStringList &texts, QWidget *parent = 0)
But if your delegate widget is the same for all the column, you'd better create a local widget on the constructor of the delegate and save its sizes one time for all, then in sizeHint you return the saved sizes:


CheckBoxDelegate::CheckBoxDelegate(const QStringList &texts, QObject *parent)
: QStyledItemDelegate(parent), texts(texts)
{
CheckBoxDelegateWidget editor(texts);
widgeSizeHint_ = editor.sizeHint();
}

QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
return widgeSizeHint_;
}

Digging in the Qt source code I've found:

QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
which is what we need, but is a private function of QAbstractItemView. I think it is because the editor are created only when needed (when you double click a cell), so if it isn't created and you call this function, it creates a new editor but for the ItemView no editor is open so it doesn't know when delete it and it remains in memory.

The Storm
20th September 2010, 14:43
Nice hint but in my case will not work because my custom widget sizeHint() changes dynamically depending on the contents in it.

When I create the editor I have other data class which I use to populate the data in the editor widget. After the data is populated the size hint will be calculated. The constructor for the delegate is called only once per item, and if my custom editor changes it's sizeHint the item will not be with proper size.

I have tried with mutable variable which I use in the function createEditor() to obtain correct sizeHint but it seems that it is too late, because the TreeView had already called the virtual funtion sizeHint() and I get improper item sizes...

I hope I was able to explain my case clear and that there is solution to this. :)

Nero
20th September 2010, 15:04
Maybe I've lost you, but as tbscope said, something like this doesn't work?

QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
CheckBoxDelegateWidget editor( yourClassDataList.value( index.row() ) );
return editor.sizeHint();
}

The Storm
20th September 2010, 18:42
Yes this will do the trick. The only thing is that both methods are "hacks" and leads to overhead... Anyway if this is the only way I don't have much of a choise. :)