В QTableWidget изменение цвета текста выбранной строки
Я использую QTableWidget для отображения нескольких строк. Некоторые из этих строк должны отражать ошибку, и их цвет текста изменяется:
Строки, отражающие отсутствие ошибки, отображаются цветом по умолчанию (черный текст на белом фоне на моем компьютере).
Строки, отражающие наличие ошибки, отображаются красным цветом текста (это красный текст на белом фоне на моем компьютере).
Все это прекрасно, пока нет выбора. Как только выбрана строка, независимо от невыбранного цвета текста, Цвет текста всегда становится белым (на моем компьютере) на синем фоне.
Это то, что я хотел бы изменить, чтобы получить следующее:
При выборе строки, если строка отражает отсутствие ошибки, я хотел бы, чтобы она отображалась с белым текстом на синем фоне (поведение по умолчанию).
Если строка отражает ошибку и выбрана, я бы хотел, чтобы она отображалась красным текстом на синем фоне.
Пока у меня есть только удалось изменить цвет выделения для всего QTableWidget, что не то, что я хочу !
5 ответов:
Отвечая самому себе, вот что я в итоге сделал : делегат.
Этот делегат будет проверять роль цвета переднего плана элемента. Если этот цвет переднего плана не является цветом текста окна по умолчанию палитры, это означает, что задан определенный цвет и этот конкретный цвет используется для выделенного цвета текста.
Я не уверен, что это очень надежно, но, по крайней мере, он отлично работает на Windows.
class MyItemDelegate: public QItemDelegate { public: MyItemDelegate(QObject* pParent = 0) : QItemDelegate(pParent) { } void paint(QPainter* pPainter, const QStyleOptionViewItem& rOption, const QModelIndex& rIndex) const { QStyleOptionViewItem ViewOption(rOption); QColor ItemForegroundColor = rIndex.data(Qt::ForegroundRole).value<QColor>(); if (ItemForegroundColor.isValid()) { if (ItemForegroundColor != rOption.palette.color(QPalette::WindowText)) { ViewOption.palette.setColor(QPalette::HighlightedText, ItemForegroundColor); } } QItemDelegate::paint(pPainter, ViewOption, rIndex); } };Вот как его использовать:
QTableWidget* pTable = new QTableWidget(...); pTable->setItemDelegate(new MyItemDelegate(this));
Он выглядит нормально, но вы можете посмотреть документацию
QStyleOptionон может сказать вам, выбран ли нарисованный элемент или нет, вам не нужно смотреть на цвет рисования, чтобы сделать это. Я бы, вероятно, дал классу модели роль пользователя, которая возвращает, являются ли данные допустимыми или нет, а затем принимает решение о цвете на основе этого. Т. е.rIndex.data(ValidRole)вернет, являются ли данные по этому индексу действительными или нет.Я не знаю, пытались ли вы переопределить данные для BackgroundRole и вернуть a пользовательский цвет, Qt может сделать правильную вещь, если вы измените цвет там
То, что вы хотите сделать, это подключить сигнал
selectionChanged(), испускаемый Qtablewidget QItemSelectionModel к слоту, скажемOnTableSelectionChanged(). В своем слоте вы можете использовать QStyleSheets для установки цветов выбора следующим образом:if (noError) { pTable->setStyleSheet("QTableView {selection-background-color: #000000; selection-color: #FFFFFF;}"); } else { pTable->setStyleSheet("QTableView {selection-background-color: #FF0000; selection-color: #0000FF;}"); }
Вы, конечно, можете наследовать от виджета таблицы и переопределить событие paint, но я не думаю, что это то, что вы хотите сделать.
Вместо этого следует использовать функцию
QAbstractItemDelegate. Вы можете либо создать один, который всегда будет использоваться для строк ошибок, и настроить строки ошибок на использование этого делегата, либо создать общий, который знает, как рисовать оба типа строк. Второй метод-это то, что я бы рекомендовал. Затем ваш делегат рисует строки соответствующим образом, даже для выбранной строки.
Для этого можно использовать, например, модель прокси , где вы возвращаете другой цвет, если у вас есть ошибка для конкретного modelindex;
QVariant MySortFilterProxyModel::data(const QModelIndex & index, int role = Qt::DisplayRole) { // assuming error state and modelindex row match if (role==Qt::BackgroundRole) return Qt::red; }
Comments