PDA

View Full Version : Delegates and Table



ankurjain
25th April 2006, 05:05
Hi all,

How can i hav different delegates in different columns of a table. for instance, i want spinbox delegate in 2nd column and combobox in 4 column.

i took an example of spinbox delegate from examples directories and tried to do the changes:



/*
main.cpp

A simple example that shows how a view can use a custom delegate to edit
data obtained from a model.
*/

#include <QApplication>
#include <QHeaderView>
#include <QItemSelectionModel>
#include <QStandardItemModel>
#include <QTableView>
#include <QObject>

#include "delegate.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QStandardItemModel model(4, 2);
QTableView tableView;
tableView.setModel(&model);

SpinBoxDelegate delegate;
ComboBoxDelegate comDel;


for (int row = 0; row < 4; ++row)
{
for (int column = 0; column < 1; ++column)
{
tableView.setItemDelegate(&comDel);
QModelIndex index = model.index(0, 0, QModelIndex());
}
for (int column = 1; column < 2; ++column)
{
tableView.setItemDelegate(&delegate);
QModelIndex index = model.index(1, 1, QModelIndex());
}
}

tableView.setWindowTitle(QObject::tr("Spin Box Delegate"));
tableView.show();

return app.exec();
}




/*
delegate.cpp

A delegate that allows the user to change integer values from the model
using a spin box widget.
*/

#include <QtGui>

#include "delegate.h"


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

QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QSpinBox *editor = new QSpinBox(parent);
editor->setMinimum(0);
editor->setMaximum(100);
editor->installEventFilter(const_cast<SpinBoxDelegate*>(this));

return editor;
}

void SpinBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::DisplayRole).toInt();

QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->setValue(value);
}

void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
spinBox->interpretText();
int value = spinBox->value();

model->setData(index, value);
}

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

/************************************************** *********************************************/


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

QWidget *ComboBoxDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QComboBox *editor = new QComboBox(parent);
QStringList list ;
list << "ankur" << "mitesh";
editor->addItems(list);
editor->installEventFilter(const_cast<ComboBoxDelegate*>(this));

return editor;
}

void ComboBoxDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::DisplayRole).toString();

QComboBox *comboBox = static_cast<QComboBox*>(editor);
comboBox->addItem(value);
}

void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
QString value = comboBox->currentText();

model->setData(index, value);
}

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

/************************************************** *********************************************/




#ifndef DELEGATE_H
#define DELEGATE_H

#include <QItemDelegate>
#include <QModelIndex>
#include <QObject>
#include <QSize>
#include <QSpinBox>

class SpinBoxDelegate : public QItemDelegate
{
Q_OBJECT

public:
SpinBoxDelegate(QObject *parent = 0);

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;

void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;

void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

class ComboBoxDelegate : public QItemDelegate
{
Q_OBJECT

public:
ComboBoxDelegate(QObject *parent = 0);

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;

void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;

void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

#endif



is there somehwere i m wrong .....

jpn
25th April 2006, 06:05
You can only set one item delegate per view. That particular item delegate may create different type of editors for different model indexes, though.

ankurjain
25th April 2006, 07:34
You can only set one item delegate per view. That particular item delegate may create different type of editors for different model indexes, though.

does different editors means the same thing that i need, i.e., combo in one column and spinbox in other ?

how can i set editor for different inedxes ?

can't the different delegate be used for different columns ?

jpn
25th April 2006, 08:04
does different editors means the same thing that i need, i.e., combo in one column and spinbox in other ? how can i set editor for different inedxes ?
Create a combo or spin box according to the model index column. Something like:


QWidget* SpinBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == something)
{
QSpinBox* editor = new QSpinBox(parent);
...
return editor;
}
else
{
QComboBox* editor = new QComboBox(parent);
...
return editor;
}
}

Just be aware that then you need to check which column is in question and cast to appropriate widget in setEditorData() and setModelData()...


can't the different delegate be used for different columns ?
Unfortunately nope. A single item delegate can be set for the whole view and it's model.

ankurjain
25th April 2006, 09:06
thanks JPN Brother ....

hey can u tell me how can i make myself conceptually more clear for qt. i find the tuts ( the desrciption ) somewhat insufficient ( not totally targeted towards brginners ).

ne resources ??

KekraU
17th May 2006, 22:58
Hi All,
This is my first post, by the way, I salute everyone.

I don't know QT very much, i'm just started few weeks ago.
Is there any way to achieve that trick by using QTableWidget / QTableWidgetItem ?
I read a tutorial about a QT3 QTable / QTableItem where it's seems to be achievable!

Use of QTableWidget::addItem ( int row, int column, QTableWidgetItem * qtwItem ) could be useful?

jpn
18th May 2006, 05:36
Is there any way to achieve that trick by using QTableWidget / QTableWidgetItem ?
If you are looking for different kinds of editors, you can use a custom item delegate with QTableWidget as well. Just be aware that the "default item delegate" QItemDelegate already offers through the QItemEditorFactory a few different editor widgets for different types of data:
- QComboBox for booleans
- QSpinBox for integers (both signed and unsigned)
- QDoubleSpinBox for doubles
- QDateTimeEdit for datetimes
- QDateEdit for dates
- QTimeEdit for times
(- QLabel for pixmaps)
- QLineEdit otherwise

A common mistake is to insert all data as text. By this way you'll end up always having a QLineEdit as the editor. You can use the method QTableWidgetItem::setData() to set different kinds of data for an item.

If you just want to place some widgets persistently in the cells, you may use cell widgets (http://doc.trolltech.com/4.1/qtablewidget.html#setCellWidget).

ankurjain
18th May 2006, 07:19
Use of QTableWidget::addItem ( int row, int column, QTableWidgetItem * qtwItem ) could be useful?

hi kekrau,
i m using qt-4.1.2 but i can't find the function that u mentioned in qtablewidget. :(

Thanx jpn for giving idea to use cellWidget :)

KekraU
18th May 2006, 19:47
Thxs JPN.
I have already looked at these Editors...
I think the main point with these Editors (you mentionned) that they could be use outside TableView... to edit these kind of data (Time, Date, DateTime, Integer, and so on...) in QTableView/QTableWidget you have to include in your class which inherite from QItemDelegate, these editors.

And in fact, that is what I did to solve my problem... include Q[Editor] (ComboBox / SpinBox...) in my cell depending on the type I want to edit.
Plus, i used QTableWidget to setBackGroundColor... Really funny SpinBox on Red Background :)

@Ankurjain:
In fact, I search on the website, and I did not find QTableWidget::addItem, but on my 4.1.0 I have it.... But you got QTableWidget::setItem( int row, int column, QTableWidgetItem * item ) which has the same prototype and seems to do the same as previous addItem

Your link (http://doc.trolltech.com/4.1/qtablewidget.html#setItem) :)