I have a QListView
where I'd like to display a simple widget with a progress bar and some other fields (and some context menu, maybe, but currently I just want to display the widget). The list has a model under it, and the model successfully delivers a string to the list and everything works fine without the delegate.
Now with the delegate, the createEditor()
method is never called. I don't understand why. I don't need to paint, but I just overrode paint()
and sizeHint()
to see whether they're called, and they are.
What I see on the QListView
is basically the simple text items. The widget never shows up (of course, since createEditor()
is never invoked).
The following is my delegate... quite basic!
class FileQueueItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
FileQueueItemDelegate(QObject *parent = 0);
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
};
And the source (also quite basic and minimal):
#include "FileQueueItemDelegate.h"
FileQueueItemDelegate::FileQueueItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}
QWidget *FileQueueItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
std::cout<<"Creating editor..."<<std::endl;
FileQueueListItem* item = new FileQueueListItem(parent);
return item;
}
void FileQueueItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
std::cout<<"Setting editor data..."<<std::endl;
FileQueueListItem* editorPtr = dynamic_cast<FileQueueListItem*>(editor);
QVariant dataResult = index.model()->data(index, Qt::DisplayRole);
editorPtr->setFilename(dataResult.toString());
}
void FileQueueItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
std::cout<<"Setting model data..."<<std::endl;
}
void FileQueueItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
std::cout<<"Updating editor geometry..."<<std::endl;
editor->setGeometry(option.rect);
}
void FileQueueItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
std::cout<<"Painting..."<<std::endl;
QStyledItemDelegate::paint(painter, option, index);
}
QSize FileQueueItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
std::cout<<"Size hint..."<<std::endl;
return QStyledItemDelegate::sizeHint(option, index);
}
I can see the prints of paint()
and sizeHint()
, but not the others (ever).
The following is the constructor of my QListView
class (I inherited it from it):
FilesQueueQList::FilesQueueQList(FilesQueue* queueObjectPtr)
{
this->internal_queue = queueObjectPtr;
this->setModel(internal_queue);
itemDelegate = new FileQueueItemDelegate(this);
this->setItemDelegate(itemDelegate);
}
And the following is its definition:
class FilesQueueQList : public QListView
{
Q_OBJECT
FilesQueue* internal_queue; //this inherits from QAbstractListModel
FileQueueItemDelegate* itemDelegate;
//...
}
And finally, this is the data()
method in the model:
QVariant FilesQueue::data(const QModelIndex &index, int role) const
{
std::cout<<"Loading data of "<<index.row()<< " "<<index.column()<<std::endl;
if ( role == Qt::DisplayRole ) {
return filesQueue[index.row()]->getFilename();
}
if(role == Qt::EditRole) {
return filesQueue[index.row()]->getFilename(); //QString this is
}
return QVariant();
}
Please assist. Let me know if you need more info. I've been trying a whole day to get this to work without any success. All I want is to get that widget (FileQueueListItem
) to be displayed on the list.
You have not implemented FilesQueue::flags(const QModelIndex &index) const
.
Default implementation makes cells only enabled and selectable.
See documentation: QAbstractItemModel::flags
Qt::ItemFlags QAbstractItemModel::flags(const QModelIndex &index) const
Returns the item flags for the given index.
The base class implementation returns a combination of flags that enables the item (
ItemIsEnabled
) and allows it to be selected (ItemIsSelectable
).