PDA

View Full Version : Delegate editor sizing problem



smacchia
6th April 2007, 21:21
I have have implemented a custom delegate and model for editing all the QTableView cells in a very controlled way. When my delegates create the editor, it doesn't fill up the available space in the cell. Is there something that I need to do to make this happen?

Thanks in advance,
Susan:confused:

marcel
8th April 2007, 10:49
Reimplement the sizeHint method, and return the cell size.

smacchia
8th April 2007, 15:17
How does the delegate find out the size of the cell? It has no direct access to the view that I know of.

marcel
8th April 2007, 16:25
Sorry about that... sizeHint is a wrong path.

Try overriding QItemDelegate::updateEditorGeometry(...);
Like this:



void MyDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem &option, const QModelIndex &index )
{
editor->setGeometry( option.rect );
}


Using option.rect should resize your editor to fit perfectly into the cell.

Regards

smacchia
8th April 2007, 17:31
Just what I was looking for! I'll give this a try.

--Susan

smacchia
9th April 2007, 14:18
Unfortunately, this method never gets called!!! I am not sure why. I have an example MVC implementation from a training class I attended and the delgates never implemented this method and the editor (spinbox or combo) was always sized correctly... Ideas?

marcel
9th April 2007, 14:29
No idea why it isn't called, but take a look at the Spin Box delegate example in the Qt Demos ( Item Views section ).

It does something similar to what you want.

smacchia
9th April 2007, 14:37
I think its not called because in the Qt source for QItemDelegete, it isn't virtual!! (it is supposed to be). Stepping through the Qt code for creating the delegate editor, it invokes QItemDelegate::updateEditorGeometry, not my derivation! I'll look at the example that you site, but I think this is the culprit. My example from the class is pretty straight forward too and doesn't event reimplement that method... :(

marcel
9th April 2007, 14:43
void QItemDelegate::updateEditorGeometry ( QWidget (http://www.qtcentre.org/forum/qwidget.html) * editor, const QStyleOptionViewItem (http://www.qtcentre.org/forum/qstyleoptionviewitem.html) & option, const QModelIndex (http://www.qtcentre.org/forum/qmodelindex.html) & index ) const [virtual] Updates the editor for the item specified by index according to the style option given.
Reimplemented from QAbstractItemDelegate (http://www.qtcentre.org/forum/qabstractitemdelegate.html#updateEditorGeometry).

This is the member description from QItemDelegate. As you can see it is virtual. Also this member is public and const. Perhaps you didn't declare it as public in your class?

marcel
9th April 2007, 14:47
Actually you're right. I just took a look at QItemDelegate.h and the member is not virtual.
But it is in QAbstractItemDelegate. Couldn't you derive your delegate from QAbstractItemDelegate instead?

jacek
9th April 2007, 14:57
I think its not called because in the Qt source for QItemDelegete, it isn't virtual!!
It is virtual. It doesn't have to be marked as virtual in QItemDelegate definition, since it was declared as virtual in QAbstractItemDelegate.


Also this member is public and const. Perhaps you didn't declare it as public in your class?
Also make sure you didn't forget about "const". It's quite common mistake.

smacchia
9th April 2007, 15:11
Oh duh - it was the "const". Thanks! It works great now.

maximAL
7th December 2007, 12:39
i got a similar problem with delegates and a QTreeView, but i'm using editing widgets that contain other widgets, eg. a QWidget containing a QLineEdit.
first, i tried adding a layout to the container widget and adding sub-widgets to it, but the result was that the item didn't seem to be editable anymore at all (or the widget has hone somewhere / was zero-sized or whatever).
i tried overriding the setGeometry function for my subclasses but when the delegate calls setGeometry, allways the standard QWidget function is called.
i declared setGeometry as:
virtual void setGeometry(const QRect &r)

wysota
7th December 2007, 12:42
If you use a completely custom widget for editing, you need to reimplement setModelData() and setEditorData() in the delegate. And probably you need to set a proper focus policy and maybe even a focus proxy. See docs for details.

maximAL
7th December 2007, 12:48
i allready overloaded setModelData() and setEditorData(). editing works just fine - only the layout is messed up.

wysota
7th December 2007, 12:49
Can we see the code of the widget and its layouts?

maximAL
7th December 2007, 13:00
here it is, the layout stuff has been commented out:


class ItemEditor : public QWidget
{
public:
ItemEditor(QWidget *i_pParent = NULL): QWidget(i_pParent)
{
//
//QVBoxLayout *p_pLayout = new QVBoxLayout();
//this->setLayout(p_pLayout);

};

~ItemEditor(void){};

virtual QVariant data() = 0;
virtual void setData(QVariant &i_Data) = 0;

};

class ItemLineEditor : public ItemEditor
{
private:
QLineEdit *m_pLineEdit;
public:
ItemLineEditor(QWidget *i_pParent = NULL): ItemEditor(i_pParent)
{
// without layout
m_pLineEdit = new QLineEdit(this);

//using a layout doesn't work at all
//m_pLineEdit = new QLineEdit(this);
//this->layout()->addWidget(m_pLineEdit);
}

virtual QVariant data()
{
return m_pLineEdit->text();
}

virtual void setData(QVariant &i_Data)
{
this->m_pLineEdit->setText(i_Data.toString());
}

// gets never called
virtual void setGeometry(const QRect& rect)
{
ItemEditor::setGeometry(rect);
this->m_pLineEdit->setGeometry(rect);
}
};

as you may see, i'm doing this because i need a unified way of accessing the user input from different widgets (combobox, doublespinbox, lineedit etc.)

jpn
7th December 2007, 13:21
as you may see, i'm doing this because i need a unified way of accessing the user input from different widgets (combobox, doublespinbox, lineedit etc.)
Qt already supports that in form of "user properties (http://doc.trolltech.com/latest/qmetaobject.html#userProperty)".

maximAL
7th December 2007, 14:09
hmm, i actually didn't think of this.
i tried to implement it now, by ran into the problem that i can set a property for any kind of widget, but then there is no unified way to initialize the actual content of the widget.
eg, for a QLineEdit i could set the data property to the old value before editing, but how do i actually set the value as text for editing? i can't do it in the c'tor, since the property won't be set yet at this time.

wysota
7th December 2007, 16:27
1. setGeometry() is not virtual, so overriding it doesn't make much sense,
2. You never set the geometry of the line edit - you should either be using layouts or reimplement resizeEvent() and use setGeometry() to set the geometry of all child widgets
3. I don't really know what you mean about a unified way to initialize the contest, but maybe seeing how it is done for a widget mapper helps:
http://doc.trolltech.com/qq/qq21-datawidgetmapper.html#usingdelegatestoofferchoices (what's important is the content of set*Data methods).