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


Автор: AndAnd 13.5.2010, 10:42
Здравствуйте форумчане!

Помогите решить проблему со стилями отображения в разных ОС.

Постановка задачи:
Имеется QTreeView, в котором соответственно строится дерево (модель на основе QStandardItemModel). Необходимо в некоторых элементах (QStandardItem) изменить содержимое, т.е. простое SetData("Text", Qt::DisplayRole) не годится, а нужна возможность вставки изображения среди текста (не в начале!!!). При этом необходимо сохранить стили выделения строк для различных ОС.
на скриншоте я хотел показать в чём проблема. В классическом теме Windows при выделении строк текст подкрашивается белым (согласно этому стилю), а в стиле Aero цвет текста никак не меняется, при этом имеется прозрасность самого выделения. Мне нужно сделать чтобы при смене темы в моей программе подобные списки отображались согласно выбранного стиля, встроенными средствами QT без подбора цветов для каждой темы и т.д.

Используемые средства:
Windows 7; MSVC 2008 with Qt integration; Qt ver. 4.4.3

Мое решение:
В общем задачу с выделением я решил, а вот с текстом никак не получается.

Создал свой делегат унаследованный от QStyledItemDelegate и в нём переопределил метод paint(...), в котором собственно и меняю само содержимое ячеек для отображения. Вот исходники:

Код


#pragma once

#include <QStyledItemDelegate>

class MyDelegate : public QStyledItemDelegate
{
    public:
        MyDelegate(QObject *parent = 0);
        ~MyDelegate();

    private:
        void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
};



Код


MyDelegate::MyDelegate(QObject *parent)
                :QStyledItemDelegate(parent)
{
}

MyDelegate::~MyDelegate()
{
}

void MyDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option,
                                 const QModelIndex & index ) const
{
// В роли Qt::UserRole содержатся данные для отображения

    QVariant value = index.data(Qt::UserRole);
    
// Этот кусок кода позволяет отображать QStandardItem  в соответствии    
    QStyleOptionViewItemV4 opt = option;
    initStyleOption(&opt, index);

    const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(&option);
    const QWidget *widget = v4->widget;
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);

// Дальше рисую текст
              int leftTab = 100;

    QRect leftRect(option.rect.x() + 5, option.rect.y() + 5, leftTab, option.rect.height());
    painter->drawText(leftRect, Qt::AlignLeft, "This picture");

// Рисуется изображение
              painter->drawPixmap(backgroundRect, QPixmap(":/Resources/delegatePicture.png"));

// Продолжение текста
              leftTab += 16; // предполагаемые размер изображения в ширину
              QRect rightRect(option.rect.x() + leftTab + 10, option.rect.y() + 5, option.rect.width() - leftTab, option.rect.height());

              painter->drawText(rightRect, Qt::AlignLeft, "painted from QStyledItemDelegate");
}


вот собственно и весь код моего делегата. 

Я здесь не стал писать painter->setPen(option.palette.highlightedText());, т.к. цвет всегда белый (не подходит для стиля Aero в Windows 7), самому устанавливать тоже не вижу смысла, т.к. не полутся той универсальности о которой писал выше.
Цитата

QPalette::HighlightedText        13              A text color that contrasts with Highlight. By default, the highlighted text color is Qt::white.


Как я понял вся проблема состоит вот в этой строке
initStyleOption(&opt, index);
т.е. если бы можно как-то вместо index передать то что я сам нарисовал с помощью painter.

Автор: AndAnd 13.5.2010, 13:54
В общем пришёл к выводу что правильней будет так


Код

void MyDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option,
                                 const QModelIndex & index ) const
{
              QVariant value = index.data(Qt::UserRole);

    QStyleOptionViewItemV4 opt4 = option;
    initStyleOption(&opt4, index);

    const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(&option);
    const QWidget *widget = v4->widget;
    QStyle *style = widget ? widget->style() : QApplication::style();
    style->drawControl(QStyle::CE_ItemViewItem, &opt4, painter, widget);

    painter->save();

    int leftTab = 100;

    QRect leftRect(option.rect.x() + 5, option.rect.y() + 5, leftTab, option.rect.height());
    style->drawItemText(painter, leftRect, Qt::AlignLeft, v4->palette, v4->state & QStyle::State_Enabled, "This picture", QPalette::WindowText);
        
    QRect backgroundRect(option.rect.x() + leftTab + 5, option.rect.y() + 5, 18, 18);
    style->drawItemPixmap(painter, backgroundRect, Qt::AlignCenter, QPixmap(":/Resources/delegatePicture.png"));
    
    leftTab += 16;
    
    QRect rightRect(option.rect.x() + leftTab + 10, option.rect.y() + 5, option.rect.width() - leftTab, option.rect.height());
    
    style->drawItemText(painter, rightRect, Qt::AlignLeft, v4->palette, v4->state & QStyle::State_Enabled, "painted by QStyledItemDelegate", QPalette::WindowText);

    painter->restore();
}


теперь остальсо правильно получить v4->palette, которая используется при отрисовке текста и как это сделать я пока не придумал.

т.е. повторюсь, а то возможно суть проблемы не понята, конкретно на примерах (см. вложения первого сообщения):
1) для Упрощённого стиля Windows цвет текста при выделении должен быть белым, а индикатор (или как её назвать - полоска) выделения - синим.
2) для стиля Windows Aero цвет текста остаётся прежним, а сам индикатор выделения прозрачный с голубым оттенком  smile

при данном решении правильно работает пункт 2, в первом пункте цвет текста не меняется на белый при выделении.

Автор: AndAnd 20.5.2010, 08:34
Никто помочь не может?  smile 

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