PDA

View Full Version : How can I modify the SpinBox Delegate Example to work in my code?



bbad68
21st January 2010, 00:37
Okay, so I really am totally new to all this, so bear with me :).

I want to make a table that has two columns; one with the name of a specific property (ie distance) and the other with a double spin box in which the user can enter a value. Yesterday it was suggested to me on this forum that I use the SpinBox Delegate example to help me out. I did, but I didn't really understand any of it (did I mention that I'm totally new to this??), mainly because I didn't understand the concept of model/view programming and delegates in general. So in the end I just copy-pasted the code (with a few minor modifications) into mine, praying that it would work. As you might guess, it didn't. The code actually compiles, but nothing appears in the listView object (which I created in the ui file). Please help!

Here is the .cpp file in which the tableView object is modifed:


warmup::warmup(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
QStandardItemModel model(4,2);
ui.tableView->setModel(&model);

SpinBoxTable table;
ui.tableView->setItemDelegate(&table);

ui.tableView->horizontalHeader()->setStretchLastSection(true);

for (int row = 0; row < 4; ++row) {
for (int column = 0; column < 2; ++column) {
QModelIndex index = model.index(row, column, QModelIndex());
model.setData(index, QVariant((row+1) * (column+1)));
}
}
}

Here is the delegate header file:


#ifndef SPINBOXTABLE_H
#define SPINBOXTABLE_H

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

class SpinBoxTable : public QItemDelegate
{
Q_OBJECT

public:
SpinBoxTable(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

...and here is the delegate .cpp file:


#include "spinboxtable.h"

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

QWidget *SpinBoxTable::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
editor->setMinimum(0.0);
editor->setMaximum(10000.00);

return editor;
}

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

QDoubleSpinBox *doubleSpinBox = static_cast<QDoubleSpinBox*>(editor);
doubleSpinBox->setValue(value);
}

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

model->setData(index, value, Qt::EditRole);
}

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

Thanks!

ChrisW67
21st January 2010, 02:08
You're certainly on the right track.

Line 8 of the first listing declares a variable that goes out of scope at the end of the warmup() method. You almost certainly want the delegate lifetime to be longer than that, i.e. long enough to get back to the event loop. Allocate it on the heap with a suitable QObject parent so that Qt cleans up for you later.

Your delegate should derive from QStyledItemDelegate to get the best match to the host environment.

See if that gets you any further.

numbat
21st January 2010, 10:45
According to the documentation and my testing, you should get a double spin box if you provide double data in the model. No delegate required.


model.setData(index, 2.2);

ChrisW67
21st January 2010, 23:02
Without a delegate, passing a QVariant::Double gives you a default, unlimited double spin box. The OP seems to want to limit the input to between 0.0 and 10000.0 (lines 13, 14 of the delegate) which, AFAICT, is only achievable with a delegate.