Qt: разделительная строка QListWidget после отдельных элементов?

Это связано с Qt: разделительная линия QListWidget между элементами? Но это выше ответ добавляет строку-разделитель после каждого элемента, я хотел бы знать, как добавить строку-разделитель после определенных элементов.


person Maverick33    schedule 10.07.2014    source источник
comment
Я не думаю, что этот трюк со стилями здесь применим. Рассматривали ли вы возможность добавления специальных элементов в качестве разделителей? Эти элементы должны были бы определять setSizeHint(), поэтому их высота мала, а также setFlags() должен определять Qt::NoItemFlags, поэтому элемент нельзя выбрать и т. д. О, и вам нужно найти способ нарисовать горизонтальную линию в элементе. ;) Возможно, попробуйте с QListWidget::setItemWidget() и поместите туда QFrame, форма которого установлена ​​на QFrame::HLine.   -  person Googie    schedule 10.07.2014
comment
Да, мне нравится эта идея. Позвольте мне попробовать это, спасибо за предложение. И в ответ я предполагаю, что @KaxukiCP перепутал его с конкретным виджетом списка, а не с тем же виджетом и после определенного элемента.   -  person Maverick33    schedule 10.07.2014
comment
@Googie Спасибо за предложение. Это сработало :) Вы должны добавить это как ответ. Однако у меня есть еще один небольшой вопрос - посмотрите, можете ли вы помочь здесь. Я хочу добавить некоторый зазор с каждой стороны этой разделительной линии/рамки. Как я могу добиться этого, любой указатель будет очень полезен.   -  person Maverick33    schedule 17.07.2014


Ответы (3)


Создайте QListWidgetItem, представляющий разделитель. Такой элемент должен был бы определять setSizeHint(), поэтому его высота мала, а также setFlags() должен определять Qt::NoItemFlags, чтобы элемент нельзя было выбрать и т. д. Затем, после добавления элемента в QListWidget, поместите QFrame с его формой. установите QFrame::HLine в качестве виджета элемента (используя QListWidget::setItemWidget()).

Что касается вашего дополнительного вопроса из комментария, а именно:

Я хочу добавить некоторый зазор с каждой стороны этой разделительной линии/рамки. Как я могу этого добиться?

Единственное решение, которое сейчас приходит мне на ум, это встроить QFrame в другой QWidget и поместить QWidget в качестве виджета элемента (помните, что вам нужно добавить менеджер компоновки в QWidget, чтобы что-то встроить в него). Затем установите правильные поля для виджета: QWidget::setContentsMargins(int left, int top, int right, int bottom)

person Googie    schedule 18.07.2014
comment
Также, чтобы отключить зависание элемента-разделителя, добавьте ui-›listWidget-›setStyleSheet(QListWidget::item:disabled { background: Transparent; }); - person Jeka; 08.10.2015

Я нашел другую возможность и протестировал ее на этот раз: p Вы можете создать новый класс, наследующий QStyledItemDelegate, который будет выглядеть следующим образом:

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)));
    }
}

И для каждого QListWidgetItem вы можете сделать следующее:

// Qt::UserRole + 1 => Must match the role set in the delegate
item->setData(Qt::UserRole + 1, true);

Установите обычай в свой QListWidget, как это

listWidget->setItemDelegate(new MyStyledItemDelegate());

Он нарисует черную линию под текстом элемента, если для Qt::UserRole + 1 установлено значение true.

person KazukiCP    schedule 10.07.2014

Вы можете попробовать использовать тот же трюк с динамическими свойствами.

myListWidget->setStyleSheet( "QListWidget::item[separator="true"] { border-bottom: 1px solid black; }" );

И на виджете вы хотите, чтобы линия была нарисована:

myWidget->setProperty("separator", true);

Однако будьте осторожны, в документации говорится:

Предупреждение: Если значение свойства Qt изменится после установки таблицы стилей, может потребоваться принудительное перерасчет таблицы стилей. Один из способов добиться этого — отключить таблицу стилей и установить ее снова.

person KazukiCP    schedule 10.07.2014
comment
Это применит разделитель к каждому элементу виджета списка. Вопрос в том, как применять разделители под определенными элементами в том же виджете списка. - person Googie; 10.07.2014
comment
Есть небольшая разница, в sylesheet я добавляю селектор свойств. В каждом виджете он будет проверять, является ли разделитель свойств истинным значением. Если нет или свойство не существует, стиль не должен применяться. - person KazukiCP; 10.07.2014
comment
В этом решении есть 2 ошибки: 1. Вы устанавливаете свойство для всего виджета списка, а не для его отдельных элементов. 2. Элементы в QListWidget (QListWidgetItem) не являются QObject и поэтому не могут содержать динамические свойства. - person Googie; 10.07.2014
comment
@KazukiCP Я хочу добавить разделительную строку в зависимости от содержимого каждого элемента, а не каждого виджета. - person Maverick33; 10.07.2014
comment
Ой, Гуги прав. Я забыл о том, что QListWidgetItem не является QObject. Нужно проверить перед публикацией ›_‹ - person KazukiCP; 10.07.2014