Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > [QT] Как раскрасить строки QListView


Автор: Brodyaga 19.1.2010, 23:18
Всем доброго времени суток!
Мне нужно закрасить фон некоторых строк в QListView определённым цветом. Поделитесь опытом кто делал такое?

P.S.
Отображаемые данные находятся под управлением модели основанной на QAbstractListItem, может в этом направлении нужно копать?

Автор: KADABRA 19.1.2010, 23:32
Brodyaga, 
Цитата(Brodyaga @  19.1.2010,  23:18 Найти цитируемый пост)
Отображаемые данные находятся под управлением модели основанной на QAbstractListItem, может в этом направлении нужно копать? 

Тогда просто, в переопределённом методе
QVariant QAbstractItemModel::data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
для параметра role == Qt::BackgroundColorRole возвращаем нужный цвет.

Автор: chaos 20.1.2010, 08:30
Brodyaga, не помню кто-то тут сказал: "Делегаты наше все"

Автор: sergey_85 20.1.2010, 09:10
Привет!

Попробуй использовать QItemDelegate, переопредели метод 
void QItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const   [virtual]

Код

void QItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const   [virtual]
Renders the delegate using the given painter and style option for the item specified by index.
When reimplementing this function in a subclass, you should update the area held by the option's rect variable, using the option's state variable to determine the state of the item to be displayed, and adjust the way it is painted accordingly.
For example, a selected item may need to be displayed differently to unselected items, as shown in the following code:
     if (option.state & QStyle::State_Selected)
         painter->fillRect(option.rect, option.palette.highlight());

     int size = qMin(option.rect.width(), option.rect.height());
     int brightness = index.model()->data(index, Qt::DisplayRole).toInt();
     double radius = (size/2.0) - (brightness/255.0 * size/2.0);
     if (radius == 0.0)
         return;

     painter->save();
     painter->setRenderHint(QPainter::Antialiasing, true);
     painter->setPen(Qt::NoPen);
     if (option.state & QStyle::State_Selected)
         painter->setBrush(option.palette.highlightedText());
     else
     ...
After painting, you should ensure that the painter is returned to its the state it was supplied in when this function was called. For example, it may be useful to call QPainter::save() before painting and QPainter::restore() afterwards.
Reimplemented from QAbstractItemDelegate.
See also QStyle::State.



Можно глянуть Qt пример Qt Examples SpinBox Delegate

 smile 

Автор: Brodyaga 20.1.2010, 11:54
Мне нужно раскрасить строку не в момент редактирования и не при проводе мышкой над строкой, а при выполнении условий определённых. Как мне сделать так, чтобы метод paint вызвался для всех индексов в модели? в какой момент он вообще вызывается?

Автор: chaos 20.1.2010, 16:13
Цитата(Brodyaga @ 20.1.2010,  08:54)
Мне нужно раскрасить строку не в момент редактирования и не при проводе мышкой над строкой, а при выполнении условий определённых. Как мне сделать так, чтобы метод paint вызвался для всех индексов в модели? в какой момент он вообще вызывается?

пока еще не было задач по реализации своего делегата, но следуя логике:

1. метод paint вызовется для всех видимых item'ов
2. вызывается метод paint тогда, когда необходимо показать item'ы + принудительно

Добавлено через 13 минут и 14 секунд
Цитата(Brodyaga @  19.1.2010,  20:18 Найти цитируемый пост)
закрасить фон некоторых строк

если только так, то что мешает заюзать QTableWidget ?
Наполняем его QTableWidgetItem и при каких хотите условиях у item'а меняете фон 

Код

QTableWidgetItem::setData(Qt::BackgroundColorRole, QColor);

Автор: chaos 20.1.2010, 16:28
поторопился - последний предложенный способ будет работать "как надо" в случае 1го столбца иначе придется извращаться - всем item'ам с row = N менять цвет

Автор: Brodyaga 20.1.2010, 17:01
Цитата

если только так, то что мешает заюзать QTableWidget ?
Наполняем его QTableWidgetItem и при каких хотите условиях у item'а меняете фон 

Тем, что у меня есть объекты для наполнения свои, и использую я QListView, так как колонка всегда одна.

Автор: chaos 20.1.2010, 17:08
Цитата(Brodyaga @  20.1.2010,  14:01 Найти цитируемый пост)
и использую я QListView, так как колонка всегда одна
 вывод не ясен.


Цитата(Brodyaga @  20.1.2010,  14:01 Найти цитируемый пост)
Тем, что у меня есть объекты для наполнения свои

не знал бы я про то что можно заюзать "MVC" 
то сделал бы так
Код

ui->tableWidget->setRowCount(SomeObjectArray.count());
int n = 0;
foreach(SomeObject *obj, SomeObjectArray) {
    QTableWindgetItem *item = new QTableWidgetItem("blablabla");
    item->setData(Qt::User, obj);
    ui->tableWidget->setItem(item, n++, 0);
}



Автор: KADABRA 20.1.2010, 19:16
Зачем так всё усложнять?
Приведённое мной решение позволяет в две строки решить эту задачу.
Цитата(Brodyaga @  19.1.2010,  23:18 Найти цитируемый пост)

Отображаемые данные находятся под управлением модели основанной на QAbstractListItem, может в этом направлении нужно копать? 

В этой модели, в методе
Код

QVariant data ( const QModelIndex & index, int role ) const

пишем
Код

    if(role == Qt::BackgroundColorRole)
        return QVariant(QColor(qrand() % 255, qrand() % 255, qrand() % 255));    // или цвет, какой нужен

Автор: Brodyaga 20.1.2010, 19:31
Цитата

Зачем так всё усложнять?
Приведённое мной решение позволяет в две строки решить эту задачу.

Придёться немного углубиться в задачу...
Дело в том, что подсвечивать я хочу те строки, на которые можно перетащить объект из другого QListView...
Следовательно, подсветка всегда у разных строк бывает. Как мне это в методе data предусмотреть?

Автор: KADABRA 20.1.2010, 20:43
Brodyaga, 
Цитата(Brodyaga @  20.1.2010,  19:31 Найти цитируемый пост)
Следовательно, подсветка всегда у разных строк бывает. Как мне это в методе data предусмотреть? 

Для тех что не надо подсвечивать возвращать пустой QVariant()

Автор: Brodyaga 20.1.2010, 21:19
Цитата

Для тех что не надо подсвечивать возвращать пустой QVariant()


Да нет.. как мне в методе дата узнать надо подсвечиват или не надо заранее? Где мне сохранить объект перетаскиваемый, чтобы исследовать его на предмет того, подсвечивать ли определённую строку или нет?

Автор: KADABRA 20.1.2010, 21:47
Brodyaga, 
Цитата(Brodyaga @  20.1.2010,  21:19 Найти цитируемый пост)
как мне в методе дата узнать надо подсвечиват или не надо заранее?

А зачем заранее? В момент начала перетаскивания расчитайте что и как подсвечивать (или передайте модели что перетаскиваете, чтоб прямо в data считать), можно в модели метод создать onDragHighlight, и сделайте из модели emit dataChanged или layoutChanged.

Автор: Brodyaga 21.1.2010, 13:07
Цитата

А зачем заранее? В момент начала перетаскивания расчитайте что и как подсвечивать (или передайте модели что перетаскиваете, чтоб прямо в data считать), можно в модели метод создать onDragHighlight, и сделайте из модели emit dataChanged или layoutChanged.

В момент начала перетаскивания это и есть заранее smile 

Сделал специальный сигнал, но не могу его вызвать в методе, который вызывается в момент начала перетаскивания:
Код

QMimeData* MyModel::mimeData(const QModelIndexList &indexes) const
{
 ...
 emit signalDragIndex(index);
 ...
}


Выдаёт ошибку:
Код

Error    1    error C2662: 'MyModel::signalDragIndex' : cannot convert 'this' pointer from 'const MyModel' to 'MyModel &'


Из константного метода нельзя чтоли сигнал эммитить?

Исправил этим

Код

emit const_cast<MyModel*>(this)->signalDragIndex(index);


smile))))

Автор: KADABRA 21.1.2010, 13:42
Brodyaga, 
Цитата(Brodyaga @  21.1.2010,  13:07 Найти цитируемый пост)
Из константного метода нельзя чтоли сигнал эммитить?

"Эммитить сигнал" это просто вызывать сгенерированный moc'ом метод, который не константный. Соответсвтенно нельзя.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)