Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Пантер от Апрель 14, 2009, 11:43



Название: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 11:43
1. Как задать свой цвет для курсора? Отнаследовался от QTreeVew и переопределяю:
Код
C++ (Qt)
void  QFullView::drawRow ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
QTreeView::drawRow(painter,option,index);
painter->setPen(Qt::green);
painter->drawRect(option.rect);
}
//
Вот только стандартное выделение затираем мое слева и внизу, да и артефакты остаются. Может кто объяснить как делать правильно.
2. Где и как можно задавать цвет текста итема, в зависимости от содержимого.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Rcus от Апрель 14, 2009, 11:56
2.Qt::ForegroundRole   The foreground brush (text color, typically) used for items rendered with the default delegate.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: crossly от Апрель 14, 2009, 12:35
а мот просто setPalette...??


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 12:44
Не нашел этого в палитре.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Rcus от Апрель 14, 2009, 13:07
в описании enum QPalette::ColorRole
QPalette::Highlight   A color to indicate a selected item or the current item. By default, the highlight color is Qt::darkBlue.
QPalette::HighlightedText   A text color that contrasts with Highlight. By default, the highlighted text color is Qt::white.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 13:26
Не то. Мне нужно, чтобы выделение было одного цвета, а курсор другого. Кстати, под виндой цвет курсора не зависит от цвета выделения.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 16:35
Млин, целый день в (_|_). Так ничего и не сделал. На сколько я понял, за вид курсора отвечает стиль, и через палитру или стайлшит ничего не поменять. И нарисовать вручную не получается, линия появляется только слева и сверху от итема.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: crossly от Апрель 14, 2009, 17:05
конкретизируй ... что имеется ввиду под курсором... цвет выделенного итема??


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: pastor от Апрель 14, 2009, 17:07
И нарисовать вручную не получается, линия появляется только слева и сверху от итема.

Прилепи скрин глянуть. И что такое "курсор"? focus rect?


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 17:29
Сейчас кеды обновляю и скрин сделать не могу. В дизайнере закиньте на диалог QTreeWidget, сделайте у него:
allColumnsShowFocus - true
selectionMode - NoSelection
Вот рамочка итема при предпросмотре и есть курсор.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: pastor от Апрель 14, 2009, 17:45
Вот рамочка итема при предпросмотре и есть курсор.

Сделал. Я сейчас под виндой, рамочка есть только в стиле CDE


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: pastor от Апрель 14, 2009, 17:53
Заглянув в исходники, можно увидеть как рисуется эта "рамка":

Код
C++ (Qt)
void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
                       const QModelIndex &index) const
{
...
   if (currentRowHasFocus) {
       QStyleOptionFocusRect o;
       o.QStyleOption::operator=(option);
       QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled)
                                 ? QPalette::Normal : QPalette::Disabled;
       o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)
                                                ? QPalette::Highlight : QPalette::Background);
       int x = 0;
       if (!option.showDecorationSelected)
           x = header->sectionPosition(0) + d->indentationForItem(d->current);
       o.rect.setRect(x - header->offset(), y, header->length() - x, height);
       style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
       // if we show focus on all columns and the first section is moved,
       // we have to split the focus rect into two rects
       if (allColumnsShowFocus && !option.showDecorationSelected
           && header->sectionsMoved() && (header->visualIndex(0) != 0)) {
           o.rect.setRect(0, y, header->sectionPosition(0), height);
           style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
       }
   }
....
}

Заглянув в описание QStyleOptionFocusRect, видим, что:

Цитировать
QColor QStyleOptionFocusRect::backgroundColor

This variable holds the background color on which the focus rectangle is being drawn.
The default value is an invalid color with the RGB value (0, 0, 0). An invalid color is a color that is not properly set up for the underlying window system.

значит вот что нам нужно из всего кода:

....
Код
C++ (Qt)
o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)
                                                ? QPalette::Highlight : QPalette::Background);
....

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


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 17:53
Ага. А под другими рамочка точечками. А мне нужна во всех стилях.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 18:12
pastor, походу я сегодня перенапряг мозг, так что теперь вообще ничего не понимаю. Не можешь ли, если не затруднит, написать как должен выглядеть код, чтобы рисовалась рамка с цветом Qt::green?


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: pastor от Апрель 14, 2009, 18:32
Я думаю так должно работать:

Код
C++ (Qt)
void  QFullView::drawRow ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
          QStyleOptionViewItem opt(option);
          QPalette p = opt.palette;
          p.setColor(QPalette::Highlight, Qt::green);
          opt.palette = p;
          opt.showDecorationSelected = true;
QTreeView::drawRow(painter,opt,index);
}


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 18:46
Не то. Ты задал цвет выделения, но не цвет рамки.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 18:55
Вот решение проблемы:
Код
C++ (Qt)
QTreeView::drawRow(painter,option,index);
if (index.row()==currentIndex().row())
{
QRect rect=option.rect;
rect.setHeight(rect.height()-1);
rect.setWidth(rect.width()-1);
painter->setPen(Qt::green);
painter->drawRect(rect);
}
Уменьшение ректа на единицу снизу и справа поставило все на свои места.
Спасибо Lion'у из джаббер конфы.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: pastor от Апрель 14, 2009, 19:02
Возвращается ещё раз к коду и описанию:

Код
C++ (Qt)
o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index)
                                                ? QPalette::Highlight : QPalette::Background);

Цитировать
QColor QStyleOptionFocusRect::backgroundColor

This variable holds the background color on which the focus rectangle is being drawn.

Также можешь заглянуть в исходники drawPrimitive и посомтреть как отрисовывается фокус рект. Другое дело, что это не будет работать под всеми стилями.

А какая проблема отрисовать самому? Снова таки загляни в исходники отрисовки Focus Rect


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 14, 2009, 19:17
Дык все уже отрисовал. Спасибо за помощь.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: igor_bogomolov от Апрель 15, 2009, 10:12
Уменьшение ректа на единицу снизу и справа поставило все на свои места.
Спасибо Lion'у из джаббер конфы.
Хм. А нас почему игнорируют
http://www.forum.crossplatform.ru/index.php?showtopic=2590


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 15, 2009, 11:32
igor_bogomolov: Первым был Lion, я воспользовался его подсказкой. Твой пример немного не катит из-за проблем с заданием цвета.


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: igor_bogomolov от Апрель 15, 2009, 11:44
Цитата: crossplatform
А то что painter->drawRect(option.rect) не полнстью рисуется, так попробуйте для option.rect сместить его нижнию-правую точку на один пиксел
Да, ну да ладно.

А по поводу почему
QStyleOptionFocusRect o;
o.backgroundColor = Qt::red;
искажает цвет, мне до сих пор непонятно. Если кто объяснит буду признателен. :)


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: pastor от Апрель 15, 2009, 12:14
искажает цвет, мне до сих пор непонятно. Если кто объяснит буду признателен. :)

Я писал выше, отрисовка фокус рект зависит от стиля. Поищи в исходниках Qt "PE_FrameFocusRect", и глянь как происходит отрисовка в каждом стиле. Вопросы пропадут :)


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: igor_bogomolov от Апрель 15, 2009, 12:42
Понятненько. Разобрался.
Для Windows style, в исходниках цвет преобразуется следущим образом
Код
C++ (Qt)
QColor patternCol((bg_col.red() ^ 0xff) & 0xff, (bg_col.green() ^ 0xff) & 0xff, (bg_col.blue() ^ 0xff) & 0xff);

Поэтому чтобы отображался требуемый цвет, нужно его таким же образом преобразовать обратно
QColor color = Qt::red;
Код
C++ (Qt)
QColor newcolor((color.red() ^ 0xff) & 0xff, (color.green() ^ 0xff) & 0xff, (color.blue() ^ 0xff) & 0xff);
Отрисовку "курсора" сделал так
Код
C++ (Qt)
if ((option.state & QStyle::State_HasFocus)) {
QStyleOptionFocusRect o;
o.rect = option.rect.adjusted(1,1,-1,-1);
o.QStyleOption::operator=(option);
o.state |= QStyle::State_KeyboardFocusChange;
o.state |= QStyle::State_Item;
o.backgroundColor = newcolor;
QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
}
Другие стили не смотрел :)

P.S. Что то при редактировании кода вместо пробелов кракозябры кокоето рисуются


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: dr_Begemot от Апрель 15, 2009, 13:12
У меня тоже возник вопрос...

Какой сигнал у QTreeView перехватывать, чтобы фиксить выбранный узел?


Название: Re: [4.x.x] Несколько вопросов по QTreeVew
Отправлено: Пантер от Апрель 15, 2009, 19:04
Цитата: crossplatform
А то что painter->drawRect(option.rect) не полнстью рисуется, так попробуйте для option.rect сместить его нижнию-правую точку на один пиксел
Да, ну да ладно.
Упс, извини. Я воспользовался твоим советом, но сместил на 1 пиксел вниз, вверх не подумал даже. :)