PDA

View Full Version : QItemDelegate



cyberboy
26th June 2008, 13:25
Hi everybody,

I'm currently busy playing with QAbstractItemModels and QItemDelegates.
This is de situation, I have a column warrenty date ("Geleverd op") and that's a date field in side my model, so I installed a QItemDelegate on a column QItemDelegate::setDelegateForColumn();


EDIT: I changed it to setItemDelegate for testing purpose!

But it doesn't work, it constructs the delegate but he doesn't use the delegate....

this is the code were I set the delegate:


void OrderAddWindow::setTable()
{
qDebug("OrderAddWindow::setTable(): Loading table and model");

QStringList header;
QList<QStringList> articleList;

header << "Artikel nr" << "Beschrijving" << "Bewerking" << "Prijs" << "Besteld" << "Geleverd" << "Geleverd op";


model = new ArticlesAddTableModel( articleList , header);
this->tableArticles->setModel(model);
this->tableArticles->setItemDelegate(new DateDelegate(this->tableArticles));

}

This is de delegate code:


#include "dateDelegate.h"
#include <QtGui>

DateDelegate::DateDelegate(QObject *parent)
: QItemDelegate(parent)
{
qDebug("DateDelegate::DateDelegate():Constructing delegate");
}

QWidget* DateDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index)
{
qDebug("DateDelegate::createEditor(): Creating delegate widget");
//create the view for the item
const QAbstractItemModel *model = index.model();

if(!model)
QItemDelegate::createEditor(parent, option, index);

QDateEdit *edit = new QDateEdit(parent);
edit->setDisplayFormat("dd-MM-yyyy");
return edit;
}

void DateDelegate::setEditorData(QWidget *editor, const QModelIndex& index)
{
qDebug("DateDelegate::setEditorDate(): Set data");
QDateEdit *edit = qobject_cast<QDateEdit*>(editor);

if(!edit)
QItemDelegate::setEditorData(editor, index);
edit->setDate(QDate::currentDate());

}

void DateDelegate::setModelData(QWidget *parent, QAbstractItemModel *model, const QModelIndex& index)
{
qDebug("DateDelegate::setModelData(): Set data in model");

}

and this is de model code and the subclass of the model



#include "articlesTableModel.h"
#include <QtGui>


ArticlesTableModel::ArticlesTableModel(const QList<QStringList> &data, const QStringList &header, QObject *parent)
: QAbstractTableModel(parent)
{
qDebug("ArticlesTableModel::ArticlesTableModel(): Constructing the table model");
this->articles = data;
this->header = header;
}


int ArticlesTableModel::rowCount( const QModelIndex& parent) const
{
Q_UNUSED(parent);
return articles.count();
}

int ArticlesTableModel::columnCount( const QModelIndex& parent) const
{
Q_UNUSED(parent);
return header.count();
}

QVariant ArticlesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if( Qt::Horizontal == orientation)
{
if(Qt::DisplayRole == role)
{
return header.at(section);
}
}

return QAbstractTableModel::headerData(section, orientation, role);
}

QVariant ArticlesTableModel::data(const QModelIndex &index, int role) const
{

if(!index.isValid())
return QVariant();

QStringList record = this->articles.at(index.row());

if(role == Qt::DisplayRole || role == Qt::EditRole){

return record.at(index.column());

}

return QVariant();

}

Qt::ItemFlags ArticlesTableModel::flags(const QModelIndex &index) const
{
if(!index.isValid())
return 0;

return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}


bool ArticlesTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if(index.isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)){
this->articles[index.row()][index.column()] = value.toString();
emit dataChanged(index, index);
return true;
}

return false;
}

bool ArticlesTableModel::insertRows(int row, int count, const QModelIndex &parent)
{
Q_UNUSED(parent);
QStringList emptyRecord;
for(int i = 0; i < columnCount(QModelIndex()); i++)
emptyRecord.append(QString());
beginInsertRows(QModelIndex(), row, row+count-1);
for(int i = 0; i < count; i++){
this->articles.insert(row, emptyRecord);
}
endInsertRows();

return true;
}

bool ArticlesTableModel::removeRows(int row, int count, const QModelIndex &parent)
{
Q_UNUSED(parent);
if(row-count-1 > this->articles.count() -1) return false;
beginRemoveRows(QModelIndex(), row, row+count-1);
for(int i=0; i<count; i++)
this->articles.removeAt(row);
endRemoveRows();
return true;

}




#include "ArticlesAddTableModel.h"
#include <QtGui>


ArticlesAddTableModel::ArticlesAddTableModel(const QList<QStringList> &data, const QStringList &header, QObject *parent)
: ArticlesTableModel(data, header, parent)
{
qDebug("ArticlesAddTableModel::ArticlesAddTableModel(): Constructing the add table model");
}

QList<QStringList> ArticlesAddTableModel::retreiveData()
{
return this->articles;
}


void ArticlesAddTableModel::removeRow()
{
qDebug("ArticlesAddTableModel::removeRow(): Remove row from model");
this->removeRows(rowCount(QModelIndex()) - 1, 1, QModelIndex());
}

void ArticlesAddTableModel::addRow()
{

qDebug("ArticlesAddTableModel::addRow(): Add an empty row to model");

insertRows(rowCount(QModelIndex()), 1, QModelIndex());
}


Does somebody know how to trigger createEditor() in the QItemDelegate?

Greetings,

Cyberboy

aamer4yu
26th June 2008, 16:14
I guess with double click :)

Thats how I saw in delegates examples in Qt demo ;)

cyberboy
26th June 2008, 17:36
Hmm... double click doesn't work, it just opens the normal editing mode :S Could it be something with te flags? Should I pas only the display flag? And give the widget the responsibility for the editing?

cyberboy
27th June 2008, 11:52
I also want to have multi-lined text in a table cell? Do I have to write a delegate that contains a QLabel widget or can I just enable it in the tableview?

caduel
27th June 2008, 11:58
Watch the const-qualifications...
createEditor is a const method in the base class, so it has to be const in your class, too.
You currently do not reimplement the method (as you want to), but shadow it. Your implementation is not called.
In short: add a "const".


The default delegate does support multiple lines (if broken with \n and not html tags like <br>).

HTH

cyberboy
27th June 2008, 12:32
Thanks for the reply, I added the const qualification to the createEditor function.

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


And I changed it also in the .cpp file. But it doesn't work :S

And about the multiline support, is it possible to type multilines, because when you press return the cell is changes from Qt::EditRole to Qt::DisplayRole? Or do I have to make some kind of popup widget which support multiple lines and insert it later on?

Greetings,

Cyberboy

caduel
27th June 2008, 12:39
no, not that way:

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

"const" methods are methods that must not change any members of a class
(unless they are mutable). Consult your C++ book for details.

caduel
27th June 2008, 12:41
multilines: with a QLineEdit (the default editor) it does not work.
You have to modify the delegate to return a suitable editor, e.g. a QTextEdit.
You also have to take care because the (default) eventFilter will catch the "return" key and close the editor which you do not want here.

cyberboy
27th June 2008, 13:22
I'll go for the popup widget, that seems to be a logical step :) and it will save me allot of work too.
But nobody knows why my delegate isn't working as it suppose to be?

caduel
27th June 2008, 13:32
didn't the posting sent at 13:39 help?
(put the const behind the signature, not in front the QWidget*)

cyberboy
27th June 2008, 17:41
It works thank you so much, and I'm sorry that I put the const before the method, I'm not that well know with the c++ syntax. I'm still busy with finish the book about c++ syntax. But thank you anyway!!