Как в QStyledItemDelegate для QListWidget как нарисовать выбранный элемент, чтобы он соответствовал стандартному списку?

У меня есть QStyledItemDelegate для моего виджета QList:

class MappingDisplayWidgetDelegate: public QStyledItemDelegate
{
Q_OBJECT
public:
MappingDisplayWidgetDelegate(QObject *parent=NULL);
virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
virtual QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
};

и это метод рисования выглядит так:

void MappingDisplayWidgetDelegate::paint ( QPainter * painter,
const QStyleOptionViewItem & option,
const QModelIndex & index ) const
{
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.midlight());QFontMetrics fm(option.font);

QString filename = index.data(Qt::DisplayRole).toString();

QRect outline = option.rect;
int outmid = outline.center().y();

QRect fnBound = fm.boundingRect(filename);
int fnBoundMid = fnBound.center().y();
fnBound.moveLeft(outline.left());
fnBound.translate(0, outmid - fnBoundMid);

painter->drawText(fnBound, Qt::AlignVCenter | Qt::AlignLeft, filename);

}

Теперь это работает, НО обработка State_Selected и State_MouseOver не дает таких же результатов, как списки по умолчанию. Вот снимок экрана (я работаю в системе Win7) приведенного выше кода слева и стандартный QListWidget справа. Вы можете видеть, что QListWidget имеет хорошие градиенты, в то время как мои элементы имеют только простые цвета.

введите описание изображения здесь

Я хочу нарисовать свои элементы, чтобы они соответствовали стандартным виджетам, но я не могу понять, как именно. Я не вижу в опциях ничего, что дало бы мне необходимую информацию.

Отредактировано, чтобы добавить:
Обратите внимание, что это несколько игрушечный пример. Реальный код имеет кучу других вещей, кроме одной строки, и имеет соответствующую (и работающую) функцию sizeHint. Это просто игрушка для демонстрации проблемы.

1

Решение

в исходный код для рисования этого элемента делается следующий вызов:

// draw the background
proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, widget);

Я подозреваю, что вы можете сделать что-то похожее на следующее:

style().drawPrimitive(QStyle::PE_PanelItemViewItem, option, painter, NULL);

Возможно, вам придется поиграть с option параметр, чтобы получить правильную цель прямоугольника. К сожалению, компьютер, который я сейчас использую, не настроен для проверки всего этого, поэтому YMMV.

1

Другие решения

У меня был тот же вопрос — я хотел, чтобы у меня была полностью настраиваемая функция рисования, но я воспользовался встроенной симпатичной картиной. Я попробовал приведенный ниже код, и до сих пор я обнаружил, что он прекрасно работает без негативных последствий:

void MassIndexItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const {
QStyledItemDelegate::paint(painter, option, QModelIndex());
//Above, note that rather than passing >index< to the inherited function, I pass a default, invalid index.
//Since my model's data() function returns an empty QVariant for invalid indexes,
//I get the default selection painting, but no other data is painted in any way.

//Below, I can do whatever painting I want and it will show up on top of the pretty selection paint
painter->drawEllipse(option.rect);
}
1

Я описываю это как полезное решение, хотя оно не очень удачное.

Если я ничего не помещаю в DisplayRole элемента, то я могу вызвать базовую подпрограмму QStyledItemDelegate :: paint, и она просто нарисует правильный фон, таким образом:

void MappingDisplayWidgetDelegate::paint ( QPainter * painter,
const QStyleOptionViewItem & option,
const QModelIndex & index ) const
{
QStyledItemDelegate::paint(painter, option, index);

QFontMetrics fm(option.font);

QString filename = index.data(Qt::UserRole).toString();

QRect outline = option.rect;
int outmid = outline.center().y();

QRect fnBound = fm.boundingRect(filename);
int fnBoundMid = fnBound.center().y();
fnBound.moveLeft(outline.left());
fnBound.translate(0, outmid - fnBoundMid);

painter->drawText(fnBound, Qt::AlignVCenter | Qt::AlignLeft,
filename);
}

Мне это не нравится, и я собираюсь на мгновение попробовать предложение Дейва, но если кто-то застрянет, похоже, это сработает. С другой стороны это означает, что вы не можете использовать DisplayRole, поэтому вы не можете использовать findItems в QListWidget.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector