PDA

View Full Version : slider control and combo box in grid view



steg90
20th November 2007, 11:20
Hi,

Is it possible and I'm sure it is, to have a view that has a slider control in one of the columns and drop down as well as edit fields? Would you use a QTableWidget/view?

Regards,
Steve

wysota
20th November 2007, 11:22
Yes. You need to use QTableView or QTableWidget (or the tree variants) and provide a custom delegate that will create appropriate widgets as editors.

steg90
20th November 2007, 11:44
Hi,

Thanks for that. I guess I create a delegate for the drop down box derived from QItemDelegate :



class DropDownDelegate : QItemDelegate
{
DropDownDelegate( QObject *parent = 0 );
QWidget* createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
QModelIndex &index );

//etc...
};

DropDownDelegate::DropDownDelegate( QObject *parent ) : QItemDelegate(parent)
{
}

QWidget* DropDownDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
QComboBox *pCombo = new QComboBox( parent );
// etc...
return pCombo;
}



I would need to provide setEditorData method and setModelData and updateEditorGeometry methods?

How do I set the above delegate for say the first column of the table view?

Regards,
Steve

wysota
20th November 2007, 11:49
Thanks for that. I guess I create a delegate for the drop down box derived from QItemDelegate
You can create a single delegate for all types of editors. Just return a different widget depending on index.column() value.


I would need to provide setEditorData method and setModelData and updateEditorGeometry methods?
The default updateEditorGeometry() should be fine. As for the other two methods you should reimplement them. Again, depending on the column number cast the editor to a proper class, fetch the value and update the model (or vice versa).


How do I set the above delegate for say the first column of the table view?

QAbstractItemView::setItemDelegate(), QAbstractItemView::setItemDelegateForColumn(), QAbstractItemView::setItemDelegateForRow()

steg90
20th November 2007, 11:52
Many thanks for your help and quick response ;)

Steve

steg90
20th November 2007, 15:09
Hi again,

I've now got a QTableView which displays a QProgressBar in column one. I want to display a check box in column two. My thinking is I could go ahead and do another custom delegate for this or within the createEditor function have the following :



QWidget *SliderDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QWidget* editor = NULL;
switch( index.column() )
{
case 1 :
{
editor = new QProgressBar(parent);
// etc
break;
}
case 2 :
{
editor = new QCheckBox(parent);
// etc
break;
}
default :
editor = QItemDelegate::createEditor( parent, option, index );
}
return editor;
}



Of course, I'd also have to do the index.column() function within the setEditorData, setModelData functions...Is this ok, or am I talking like I've not got a clue?!

Thanks,
Steve

wysota
20th November 2007, 15:19
Of course, I'd also have to do the index.column() function within the setEditorData, setModelData functions...Is this ok, or am I talking like I've not got a clue?!

Yes, it's exactly like you should implement it.

As for the progress bar you might want to go for a different approach. It's hard to call the progress bar an editor, because it only displays some data. You might instead reimplement the delegate's paint routine and paint the progress bar in the cell using QStyle. The approach was described a few time on the forum, it's probably even in the wiki.

steg90
20th November 2007, 15:33
Thanks again!

One more question...is it possible to show these widgets in the table view without having to click into a cell before they are displayed? Does this make sense???

Thanks,
Steve

steg90
20th November 2007, 16:29
Is it possible to display a slider control within the table view without having to double click on the cell?

I don't know if this is possible through delegate?

Thanks,
Steve

wysota
20th November 2007, 20:59
One more question...is it possible to show these widgets in the table view without having to click into a cell before they are displayed? Does this make sense???
Yes, that's exactly what I meant when speaking about the progress bar. Using index widgets (QAbstractItemView::setIndexWidget) is also an option, but it will get slow if you use too many of them. The same goes for every other widget of course. Search the forum - I'm sure there have been at least two or three threads about faking a progress bar using a delegate.

steg90
21st November 2007, 09:08
Hi,

So, in order to display say a QSlider within a cell in the table without first having to double click on the cell, I need to paint it myself?

Regards,
Steve

wysota
21st November 2007, 10:51
Yes, or set it as an index widget.

steg90
21st November 2007, 11:03
Hi,

I've set it as an index widget within the view. I guess I didn't need a custom delegate for it?!

This is the code I've done to set column two to use a QSlider:



QModelIndex modelIndex = m_pmodel->index(0,1,QModelIndex());
QSlider *slider = new QSlider(Qt::Horizontal,ui.tableView);
slider->setMinimum( 0 );
slider->setMaximum( 100 );
ui.tableView->setIndexWidget( modelIndex, slider );


Think I got confused with using a custom delegate, guess the use of this would have been as an editor in the table - for instance, if one of the columns I wanted an input mask?

Regards,
Steve

wysota
21st November 2007, 11:45
I've set it as an index widget within the view. I guess I didn't need a custom delegate for it?!
Correct. Just don't insert more than 10 of those :)


Think I got confused with using a custom delegate, guess the use of this would have been as an editor in the table - for instance, if one of the columns I wanted an input mask?

createEditor() returns an editor - whatever one means by that - be it a combobox or a modified QLineEdit, it doesn't matter. Another thing is displaying items. Currently your index widget has nothing to do with the item (and the model) itself - you have to program it independently of the model-view architecture.