В QTableWidget изменение цвета текста выбранной строки - PullRequest
6 голосов
/ 13 ноября 2008

Я использую QTableWidget для отображения нескольких строк. Некоторые из этих строк должны отражать ошибку, и их цвет текста изменяется:

Строки, отражающие отсутствие ошибок, отображаются цветом по умолчанию (черный текст на белом фоне на моем компьютере).
Строки, отражающие наличие ошибки, отображаются красным цветом текста (красный текст на белом фоне на моем компьютере).

Это все нормально, пока нет выбора. Как только строка выделена, независимо от невыбранного цвета текста, цвет текста всегда становится белым (на моем компьютере) на синем фоне.

Это то, что я хотел бы изменить, чтобы получить следующее:
Когда строка выбрана, если строка отражает, ошибки нет, хотелось бы, чтобы она отображалась белым текстом на синем фоне (поведение по умолчанию).
Если строка отражает ошибку и выбрана, я хочу, чтобы она отображалась красным текстом на синем фоне.

Пока мне удалось изменить цвет выделения только для всего QTableWidget, а это не то, что я хочу!

Ответы [ 5 ]

9 голосов
/ 18 ноября 2008

Отвечая себе, вот что я в итоге сделал: делегат.

Этот делегат проверит роль цвета переднего плана элемента. Если этот цвет переднего плана не является цветом палитры WindowText по умолчанию, это означает, что установлен определенный цвет, и этот конкретный цвет используется для выделенного цвета текста.

Я не уверен, что это очень надежно, но, по крайней мере, на 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));
1 голос
/ 18 июня 2009

Что вы хотите сделать, это подключить сигнал selectionChanged(), излучаемый QItemSelectionModel QTableWidget, к слоту, скажем, 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;}");
}
1 голос
/ 29 ноября 2008

Выглядит нормально, но вы можете посмотреть документацию QStyleOption, которая может сказать вам, выбран ли нарисованный элемент или нет, вам не нужно смотреть на цвет рисования, чтобы сделать это. Вероятно, я бы дал классу модели роль пользователя, которая возвращает действительные данные или нет, а затем принимаю цветовое решение на основе этого. То есть rIndex.data(ValidRole) будет возвращать, если данные по этому индексу действительны или нет.

Я не знаю, пытались ли вы переопределить данные для BackgroundRole и вернуть собственный цвет, Qt может поступить правильно, если вы измените цвет там

0 голосов
/ 02 января 2009

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

    QVariant MySortFilterProxyModel::data(const QModelIndex & index, int role = Qt::DisplayRole) {
       // assuming error state and modelindex row match
       if (role==Qt::BackgroundRole)
         return Qt::red;
   }
0 голосов
/ 13 ноября 2008

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

Вместо этого следует использовать функцию QAbstractItemDelegate. Вы можете либо создать один, который будет всегда использоваться для строк ошибок, и установить строки ошибок для использования этого делегата, либо создать общий, который знает, как рисовать строки обоих типов. Второй метод - это то, что я бы порекомендовал. Затем ваш делегат рисует строки соответствующим образом, даже для выбранной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...