This is related to Qt: QListWidget separator line between items? But this above answer adds separator line after each items, I would like to know a way to add the separator line after particular items.
Create a QListWidgetItem
representing the separator. Such item would need to have defined the setSizeHint()
, so its height is small, and also the setFlags()
should define Qt::NoItemFlags
, so the item is not selectable, etc. Then, after adding the item to the QListWidget
, place a QFrame
, with its shape set to QFrame::HLine
, as the item's widget (using QListWidget::setItemWidget()
).
As for your additional question from the comment, which is:
I want to add some gap on each sides of this separator line/frame. How can I achieve this?
The only solution that comes to my mind right now is to embed the QFrame
inside of another QWidget
and put the QWidget
as item's widget (remember that you need to add a layout manager to the QWidget
in order to embed anything in it). Then set proper margins on the widget: QWidget::setContentsMargins(int left, int top, int right, int bottom)
I found another possibility and tested it this time :p You could create a new class inheriting QStyledItemDelegate that look like this :
void MyStyledItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter, option, index);
// I have decided to use Qt::UserRole + 1 to store my boolean
// but it could be any other role while it's value is bigger than Qt::UserRole
QVariant isSeparator = index.data(Qt::UserRole + 1);
if (isSeparator.isValid() && isSeparator.toBool())
{
QRect rct = option.rect;
rct.setY(rct.bottom() - 1);
painter->fillRect(rct, QColor::fromRgb(qRgb(0, 0, 0)));
}
}
And the for each QListWidgetItem you can do the following :
// Qt::UserRole + 1 => Must match the role set in the delegate
item->setData(Qt::UserRole + 1, true);
Install the custom in your QListWidget like this
listWidget->setItemDelegate(new MyStyledItemDelegate());
It will draw a black line under the text of the item if the Qt::UserRole + 1 is set to true.
You can try using the same trick with dynamic properties.
myListWidget->setStyleSheet( "QListWidget::item[separator="true"] { border-bottom: 1px solid black; }" );
And on the widget you want the line to be drawn :
myWidget->setProperty("separator", true);
However be carefull the documentation says :
Warning: If the value of the Qt property changes after the style sheet has been set, it might be necessary to force a style sheet recomputation. One way to achieve this is to unset the style sheet and set it again.
QListWidget
(QListWidgetItem
) are not a QObject
and so they cannot hold dynamic properties. –
Orleanist © 2022 - 2024 — McMap. All rights reserved.
setSizeHint()
, so their height is small and also thesetFlags()
should defineQt::NoItemFlags
, so the item is not selectable, etc. Oh, and you need to find out the way to draw a horizontal line in the item ;) Maybe try withQListWidget::setItemWidget()
and put theQFrame
there which has a shape set toQFrame::HLine
. – Orleanist