How to create QListWidgetItem with aligned left and right text in Qt?
-
I'm trying to create a QListWidget where each QListWidgetItem displays text in two parts:
- Left-aligned text on the left side
- Right-aligned text on the right side
Example of desired layout:
I know I can add spaces between the left and right text, but this isn't reliable since:
- Font width can vary
- Widget width can change
- Text lengths are dynamic
What's the proper way to implement this kind of layout with QListWidget?
Btw, I'm using Qt 6.8 on Windows.
-
Using a custom QStyledItemDelegate like this
class CustomListWidgetItemDelegate : public QStyledItemDelegate { public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { painter->save(); if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.highlight()); else if (option.state & QStyle::State_MouseOver) painter->fillRect(option.rect, option.palette.highlight()); //left aligned if(index.data(Qt::DisplayRole).isValid()) { QString text = index.data(Qt::DisplayRole).toString(); painter->drawText(QPoint(option.rect.left() + 5, option.rect.bottom()-5), text); } //right aligned if(index.data(Qt::UserRole).isValid()) { QString text = index.data(Qt::UserRole).toString(); int textwidth = painter->fontMetrics().boundingRect(text).width(); painter->drawText(QPoint(option.rect.right() - textwidth - 5, option.rect.bottom()-5), text);; } //fixed if(index.data(Qt::UserRole + 1).isValid()) { QString text = index.data(Qt::UserRole + 1).toString(); painter->drawText(QPoint(200, option.rect.bottom()-5), text);; } painter->restore(); } };
Now that theres more than one text, the other texts are stored in UserRoles
//install delegate on the ListWidget ui->listWidget->setItemDelegate(new CustomListWidgetItemDelegate); QListWidgetItem * item = nullptr; for(int i = 0; i < 5; i++) { item = new QListWidgetItem("ListItem"); item->setData(Qt::UserRole, "Yep"); item->setData(Qt::UserRole + 1, "Maybe"); ui->listWidget->addItem(item); }
-
Use text Alignment. Did you get a chance to look at the doc here
https://doc.qt.io/qt-6/qlistwidgetitem.html#setTextAlignment -
Use text Alignment. Did you get a chance to look at the doc here
https://doc.qt.io/qt-6/qlistwidgetitem.html#setTextAlignment@dheerendra How would you use that to place some text at left and some text at right?
-
I'm trying to create a QListWidget where each QListWidgetItem displays text in two parts:
- Left-aligned text on the left side
- Right-aligned text on the right side
Example of desired layout:
I know I can add spaces between the left and right text, but this isn't reliable since:
- Font width can vary
- Widget width can change
- Text lengths are dynamic
What's the proper way to implement this kind of layout with QListWidget?
Btw, I'm using Qt 6.8 on Windows.
Maybe you want to check how
QShortcut
is implemented forQAction
andQMenu
, because this is what you are showing there. -
@JonB Read the question on more time. My interpretation was wrong. Same widget align left/right. No direct way.
-
Using a custom QStyledItemDelegate like this
class CustomListWidgetItemDelegate : public QStyledItemDelegate { public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { painter->save(); if (option.state & QStyle::State_Selected) painter->fillRect(option.rect, option.palette.highlight()); else if (option.state & QStyle::State_MouseOver) painter->fillRect(option.rect, option.palette.highlight()); //left aligned if(index.data(Qt::DisplayRole).isValid()) { QString text = index.data(Qt::DisplayRole).toString(); painter->drawText(QPoint(option.rect.left() + 5, option.rect.bottom()-5), text); } //right aligned if(index.data(Qt::UserRole).isValid()) { QString text = index.data(Qt::UserRole).toString(); int textwidth = painter->fontMetrics().boundingRect(text).width(); painter->drawText(QPoint(option.rect.right() - textwidth - 5, option.rect.bottom()-5), text);; } //fixed if(index.data(Qt::UserRole + 1).isValid()) { QString text = index.data(Qt::UserRole + 1).toString(); painter->drawText(QPoint(200, option.rect.bottom()-5), text);; } painter->restore(); } };
Now that theres more than one text, the other texts are stored in UserRoles
//install delegate on the ListWidget ui->listWidget->setItemDelegate(new CustomListWidgetItemDelegate); QListWidgetItem * item = nullptr; for(int i = 0; i < 5; i++) { item = new QListWidgetItem("ListItem"); item->setData(Qt::UserRole, "Yep"); item->setData(Qt::UserRole + 1, "Maybe"); ui->listWidget->addItem(item); }
-