Custom Delegate
-
Hi,
II'm working on a music player and I want to build a custom Delegate for my album QListWidget. I just want to add a artist name under the QListWidgetItem's title.
I have looked at some custom Delegate examples in Qt examples but they are too complicated.
Can someone tell me the simplest way? -
Hi
You could add \n (newline) between text
and it will be drawn as one item like:
My Song Title
ArtistQString Row=QString("%1\n%2").arg("My Song Title").arg("Artist"); ui->listWidget->addItem(Row);
-
Hi,
thank you. I did it. but still is there a simple example about custom delegates?And also is it possible to sort a QListWidget with item's userRole Data ( listWidgetItem->Data(Qt::UserRole) ) ?
-
Here's a little example of a delegate that takes title and artist from user roles of the index:
struct MyDelegate: public QStyledItemDelegate { MyDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {} void paint(QPainter* p, const QStyleOptionViewItem& o, const QModelIndex& idx) const override { // get the data from the index auto title = idx.data(Qt::UserRole).toString(); auto artist = idx.data(Qt::UserRole+1).toString(); //split cell rectangle into upper and lower half auto titleRect = o.rect.adjusted(0, 0, 0, -o.rect.height()/2); auto artistRect = o.rect.adjusted(0, o.rect.height()/2, 0, 0); //draw the data in their rectangles p->drawText(titleRect, Qt::AlignLeft, title); p->drawText(artistRect, Qt::AlignLeft, artist); } QSize sizeHint(const QStyleOptionViewItem& o, const QModelIndex& idx) const override { //get the default size hint auto sh = QStyledItemDelegate::sizeHint(o, idx); //modify the hint to fit 2 lines of text return QSize(sh.width(), sh.height()*2); } };
You can play around with the painter, fonts, alignment etc. but that's the basic idea.
AFAIK you can't select a role for sorting in a QListWidget, but you could use a QListView with a QStandardItemModel instead. Should be pretty similar to use and that model allows you to set a role used for sorting.
-
Hi,
Thank you for the example it helped so much.
and for the listView:
I'm using QListWdgetItem for the albums but there is no addItem or insertItem in QListView.
What should I do about that? -
When using a QListView you need to provide a model via setModel(). I suggest a QStandardItemModel. In that setup you add items to the model, not to the view, i.e. use setItem() to insert a QStandardItem.
-
Hi,
setModel in QListView takes an QAbstractItemModel not a QStandardModel. and I looked at the QAbstractItemModel and I got confused. Where are it's items? -
QAbstractItemModel is an abstract base class for models. It does not have items because not all models need them (e.g. QSqlTableModel).
QStandardModel is one of the implementations of QAbstractItemModel that Qt provides. You can pass it to the
setModel()
method. It uses QStandardItem as the item type. -
Yes you're right I made a mistake.
thank you. you helped so much -
Hi,
I did as you said but it doesn't sortQStandardItemModel *model = new QStandardItemModel;
QStandardItem *item = new QStandardItem("Daze");
QStandardItem *item2 = new QStandardItem("Jealous Gods");
model->setItem(0,item2);
model->setItem(1, item);
model->setSortRole(0);
ui->listView->setModel(model);it shows:
Jealous Gods
daze -
You need to call
sort()
to sort the model. Also you should use enums and not raw role numbers in case the value changes in the future:QStandardItemModel *model = new QStandardItemModel(someParent); //remember to give it a parent or it leaks! model->setItem(0, new QStandardItem("Jealous Gods")); model->setItem(1, new QStandardItem("Daze")); model->setSortRole(Qt::DisplayRole); // Qt::DisplayRole is default anyway, so this changes nothing model->sort(0); ui->listView->setModel(model);
-
Yes thank you so much