Qt: QListWidget separator line after particuler items?
Asked Answered
C

3

8

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.

Conspecific answered 10/7, 2014 at 8:22 Comment(3)
I don't think that stylesheet trick will apply here. Have you considered adding a special items as separators? Those items would need to have defined the setSizeHint(), so their height is small and also the setFlags() should define Qt::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 with QListWidget::setItemWidget() and put the QFrame there which has a shape set to QFrame::HLine.Orleanist
Yeah, I like this idea. Let me try this, thanks for the suggestion. And in the answer I guess @KaxukiCP confuesd it with "particular list widget" rather then the same widget and after a particular item.Conspecific
@Orleanist Thanks for the suggestion. It worked :) You should add it as an answer. However, I have one more small query - see if you can help here. I want to add some gap on each sides of this separator line/frame. How can I achieve this, any pointer would be very helpful.Conspecific
O
12

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)

Orleanist answered 18/7, 2014 at 7:32 Comment(1)
Also to disable hovering of separator item add ui->listWidget->setStyleSheet("QListWidget::item:disabled { background: transparent; }");Idaliaidalina
H
1

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.

Hawthorn answered 10/7, 2014 at 9:56 Comment(0)
H
-1

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.

Hawthorn answered 10/7, 2014 at 8:37 Comment(5)
This will apply separator under every item of the list widget. Question is how to apply separators under particular items in the very same list widget.Orleanist
There is a subtle difference, in the sylesheet I add a property selector. On each widget it will check if the property "separator" as a true value. If not or the property does not exist the style shouldn't be applied.Hawthorn
There are 2 errors in this solution: 1. You are setting property for the entire list widget, not its particular items. 2. Items in QListWidget (QListWidgetItem) are not a QObject and so they cannot hold dynamic properties.Orleanist
@Hawthorn I want to add separator line depending upon each item's content, not each widget.Conspecific
Oops, Googie is right. I forgot about the fact that QListWidgetItem isn't QObject. Should have test before posting >_<Hawthorn

© 2022 - 2024 — McMap. All rights reserved.